mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-02-10 22:02:56 +01:00
qca: ipq806x: Modified Eth and Switch drivers to read data from DTB.
Change-Id: Ie35b52a2c022c29de341c63af13c67b95f7e565a Signed-off-by: Aditya Kumar Patra S <apatr@codeaurora.org>
This commit is contained in:
parent
84d2f385fb
commit
2c97e2ff04
5 changed files with 150 additions and 45 deletions
|
|
@ -15,7 +15,7 @@
|
|||
#define _IPQ_GMAC_H
|
||||
#include <common.h>
|
||||
#include <net.h>
|
||||
#include <configs/ipq806x_cdp.h>
|
||||
#include <configs/ipq806x.h>
|
||||
|
||||
#define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ)
|
||||
#define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ)
|
||||
|
|
@ -337,6 +337,25 @@
|
|||
#define phy_reg_write(base, addr, reg, data) \
|
||||
ipq_mdio_write(addr, reg, data)
|
||||
|
||||
#define MII_BUSY (1 << 0)
|
||||
#define MII_WRITE (1 << 1)
|
||||
#define MII_CLKRANGE_60_100M (0)
|
||||
#define MII_CLKRANGE_100_150M (0x4)
|
||||
#define MII_CLKRANGE_20_35M (0x8)
|
||||
#define MII_CLKRANGE_35_60M (0xC)
|
||||
#define MII_CLKRANGE_150_250M (0x10)
|
||||
#define MII_CLKRANGE_250_300M (0x14)
|
||||
#define MII_DATA_REG_ADDR (0x14)
|
||||
#define MII_ADDR_REG_ADDR (0x10)
|
||||
#define MII_MDIO_TIMEOUT (10000)
|
||||
#define MIIADDRSHIFT (11)
|
||||
#define MIIREGSHIFT (6)
|
||||
#define MII_REGMSK (0x1F << 6)
|
||||
#define MII_ADDRMSK (0x1F << 11)
|
||||
#define MII_PHY_STAT_SHIFT (10)
|
||||
#define AUTO_NEG_ENABLE (1 << 12)
|
||||
#define FORCE_RATE_10 (0 << 13) | (1 << 15) | (1 << 8)
|
||||
#define FORCE_RATE_100 (1 << 13) | (1 << 15) | (1 << 8)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
@ -743,4 +762,48 @@ enum GmacFlowControlReg
|
|||
GmacFlowControlBackPressure = 0x00000001,
|
||||
GmacSendPauseFrame = 0x00000001, /* (FCB/PBA)send pause frm/Apply back pressure 0 RW 0 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Below is "88E1011/88E1011S Integrated 10/100/1000 Gigabit Ethernet Transceiver"
|
||||
* Register and their layouts. This Phy has been used in the Dot Aster GMAC Phy daughter.
|
||||
* Since the Phy register map is standard, this map hardly changes to a different Ppy
|
||||
*/
|
||||
enum MiiRegisters
|
||||
{
|
||||
PHY_CONTROL_REG = 0x0000, /* Control Register */
|
||||
PHY_STATUS_REG = 0x0001, /* Status Register */
|
||||
PHY_ID_HI_REG = 0x0002, /* PHY Identifier High Register */
|
||||
PHY_ID_LOW_REG = 0x0003, /* PHY Identifier High Register */
|
||||
PHY_AN_ADV_REG = 0x0004, /* Auto-Negotiation Advertisement Register */
|
||||
PHY_LNK_PART_ABl_REG = 0x0005, /* Link Partner Ability Register (Base Page) */
|
||||
PHY_AN_EXP_REG = 0x0006, /* Auto-Negotiation Expansion Register */
|
||||
PHY_AN_NXT_PAGE_TX_REG = 0x0007, /* Next Page Transmit Register */
|
||||
PHY_LNK_PART_NXT_PAGE_REG = 0x0008, /* Link Partner Next Page Register */
|
||||
PHY_1000BT_CTRL_REG = 0x0009, /* 1000BASE-T Control Register */
|
||||
PHY_1000BT_STATUS_REG = 0x000a, /* 1000BASE-T Status Register */
|
||||
PHY_SPECIFIC_CTRL_REG = 0x0010, /* Phy specific control register */
|
||||
PHY_SPECIFIC_STATUS_REG = 0x0011, /* Phy specific status register */
|
||||
PHY_INTERRUPT_ENABLE_REG = 0x0012, /* Phy interrupt enable register */
|
||||
PHY_INTERRUPT_STATUS_REG = 0x0013, /* Phy interrupt status register */
|
||||
PHY_EXT_PHY_SPC_CTRL = 0x0014, /* Extended Phy specific control */
|
||||
PHY_RX_ERR_COUNTER = 0x0015, /* Receive Error Counter */
|
||||
PHY_EXT_ADDR_CBL_DIAG = 0x0016, /* Extended address for cable diagnostic register */
|
||||
PHY_LED_CONTROL = 0x0018, /* LED Control */
|
||||
PHY_MAN_LED_OVERIDE = 0x0019, /* Manual LED override register */
|
||||
PHY_EXT_PHY_SPC_CTRL2 = 0x001a, /* Extended Phy specific control 2 */
|
||||
PHY_EXT_PHY_SPC_STATUS = 0x001b, /* Extended Phy specific status */
|
||||
PHY_CBL_DIAG_REG = 0x001c, /* Cable diagnostic registers */
|
||||
};
|
||||
|
||||
enum Mii_Phy_Status {
|
||||
Mii_phy_status_speed_10 = 0x0000,
|
||||
Mii_phy_status_speed_100 = 0x4000,
|
||||
Mii_phy_status_speed_1000 = 0x8000,
|
||||
|
||||
Mii_phy_status_full_duplex = 0x2000,
|
||||
Mii_phy_status_half_duplex = 0x0000,
|
||||
|
||||
Mii_phy_status_link_up = 0x0400,
|
||||
};
|
||||
|
||||
#endif /* _IPQ_GMAC_H */
|
||||
|
|
|
|||
|
|
@ -79,3 +79,6 @@ obj-$(CONFIG_IPQ40XX_ESS) += ipq40xx/ipq40xx_ess_sw.o
|
|||
obj-$(CONFIG_QCA8075_PHY) += ipq40xx/ipq40xx_qca8075.o
|
||||
obj-$(CONFIG_QCA8033_PHY) += ipq40xx/ipq40xx_qca8033.o
|
||||
obj-$(CONFIG_IPQ40XX_MDIO) += ipq40xx/ipq40xx_mdio.o
|
||||
obj-$(CONFIG_IPQ_SNPS_GMAC) += ipq806x/ipq_gmac_eth.o
|
||||
obj-$(CONFIG_IPQ_SWITCH_ATHRS17) += ipq806x/athrs17_phy.o
|
||||
obj-$(CONFIG_IPQ_SWITCH_QCA8511) += ipq806x/qca8511.o
|
||||
|
|
|
|||
|
|
@ -272,9 +272,9 @@ int do_ar8xxx_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
|
|||
struct athrs17_regmap *section = ®map[i];
|
||||
|
||||
for (reg = section->start; reg <= section->end; reg += sizeof(uint32_t)) {
|
||||
ipq_gmac_board_cfg_t *gmac_tmp_cfg = gboard_param->gmac_cfg;
|
||||
ipq_gmac_board_cfg_t *gmac_tmp_cfg = gmac_cfg;
|
||||
uint32_t val = athrs17_reg_read(gmac_tmp_cfg, reg);
|
||||
printf("%03zu: %08zu\n", reg, val);
|
||||
printf("%03zx: %08zx\n", reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,17 +15,15 @@
|
|||
#include <net.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-ipq806x/msm_ipq806x_gmac.h>
|
||||
#include <asm/arch-ipq806x/gpio.h>
|
||||
#include <malloc.h>
|
||||
#include <phy.h>
|
||||
#include <miiphy.h>
|
||||
#include <linux/compat.h>
|
||||
#include <asm/arch-ipq806x/nss/clock.h>
|
||||
#include <asm/arch-ipq806x/nss/nss_reg.h>
|
||||
#include <asm/arch-ipq806x/gpio.h>
|
||||
#include <asm/arch-ipq806x/clock.h>
|
||||
#include <fdtdec.h>
|
||||
#include <asm/arch-ipq806x/clk.h>
|
||||
#include <asm/arch-ipq806x/ipq_gmac.h>
|
||||
#include <asm/arch-ipq806x/msm_ipq806x_gmac.h>
|
||||
#include <asm/arch-qcom-common/gpio.h>
|
||||
|
||||
#define ipq_info printf
|
||||
#define ipq_dbg printf
|
||||
|
|
@ -33,13 +31,20 @@
|
|||
#define DESC_FLUSH_SIZE (((DESC_SIZE + (CONFIG_SYS_CACHELINE_SIZE - 1)) \
|
||||
/ CONFIG_SYS_CACHELINE_SIZE) * \
|
||||
(CONFIG_SYS_CACHELINE_SIZE))
|
||||
static struct ipq_eth_dev *ipq_gmac_macs[IPQ_GMAC_NMACS];
|
||||
|
||||
uchar ipq_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xAB, 0xBD, 0xDA};
|
||||
|
||||
static struct ipq_eth_dev *ipq_gmac_macs[CONFIG_IPQ_NO_MACS];
|
||||
static int (*ipq_switch_init)(ipq_gmac_board_cfg_t *cfg);
|
||||
static struct ipq_forced_mode get_params;
|
||||
static struct bitbang_nodes *bb_nodes[IPQ_GMAC_NMACS];
|
||||
static struct bitbang_nodes *bb_nodes[CONFIG_IPQ_NO_MACS];
|
||||
static void ipq_gmac_mii_clk_init(struct ipq_eth_dev *priv, uint clk_div,
|
||||
ipq_gmac_board_cfg_t *gmac_cfg);
|
||||
|
||||
extern ipq_gmac_board_cfg_t gmac_cfg[];
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void ipq_register_switch(int(*sw_init)(ipq_gmac_board_cfg_t *cfg))
|
||||
{
|
||||
ipq_switch_init = sw_init;
|
||||
|
|
@ -244,7 +249,7 @@ static int ipq_gmac_rx_desc_setup(struct ipq_eth_dev *priv)
|
|||
rxdesc = priv->desc_rx[i];
|
||||
rxdesc->length |= ((ETH_MAX_FRAME_LEN << DescSize1Shift) &
|
||||
DescSize1Mask);
|
||||
rxdesc->buffer1 = virt_to_phys(NetRxPackets[i]);
|
||||
rxdesc->buffer1 = virt_to_phys(net_rx_packets[i]);
|
||||
rxdesc->data1 = (unsigned long)priv->desc_rx[(i + 1) %
|
||||
NO_OF_RX_DESC];
|
||||
|
||||
|
|
@ -540,11 +545,10 @@ static int ipq_eth_recv(struct eth_device *dev)
|
|||
|
||||
|
||||
invalidate_dcache_range(
|
||||
(unsigned long)(NetRxPackets[priv->next_rx]),
|
||||
(unsigned long)(NetRxPackets[priv->next_rx]) +
|
||||
(unsigned long)(net_rx_packets[priv->next_rx]),
|
||||
(unsigned long)(net_rx_packets[priv->next_rx]) +
|
||||
PKTSIZE_ALIGN);
|
||||
|
||||
NetReceive(NetRxPackets[priv->next_rx], length - 4);
|
||||
net_process_received_packet(net_rx_packets[priv->next_rx], length - 4);
|
||||
|
||||
|
||||
rxdesc->length = ((ETH_MAX_FRAME_LEN << DescSize1Shift) &
|
||||
|
|
@ -554,7 +558,7 @@ static int ipq_eth_recv(struct eth_device *dev)
|
|||
RxDescEndOfRing : 0;
|
||||
rxdesc->length |= RxDescChain;
|
||||
|
||||
rxdesc->buffer1 = virt_to_phys(NetRxPackets[priv->next_rx]);
|
||||
rxdesc->buffer1 = virt_to_phys(net_rx_packets[priv->next_rx]);
|
||||
|
||||
priv->next_rx = (priv->next_rx + 1) % NO_OF_RX_DESC;
|
||||
|
||||
|
|
@ -714,19 +718,19 @@ static void ipq_gmac_mii_clk_init(struct ipq_eth_dev *priv, uint clk_div,
|
|||
int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
|
||||
{
|
||||
static int sw_init_done = 0;
|
||||
struct eth_device *dev[IPQ_GMAC_NMACS];
|
||||
struct eth_device *dev[CONFIG_IPQ_NO_MACS];
|
||||
uint clk_div_val;
|
||||
uchar enet_addr[IPQ_GMAC_NMACS * 6];
|
||||
uchar enet_addr[CONFIG_IPQ_NO_MACS * 6];
|
||||
uchar *mac_addr;
|
||||
char ethaddr[32] = "ethaddr";
|
||||
char mac[64];
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
int gmac_gpio_node = 0, ar8033_gpio_node = 0, offset = 0;
|
||||
memset(enet_addr, 0, sizeof(enet_addr));
|
||||
|
||||
/* Getting the MAC address from ART partition */
|
||||
ret = get_eth_mac_address(enet_addr, IPQ_GMAC_NMACS);
|
||||
ret = get_eth_mac_address(enet_addr, CONFIG_IPQ_NO_MACS);
|
||||
|
||||
for (i = 0; gmac_cfg_is_valid(gmac_cfg); gmac_cfg++, i++) {
|
||||
|
||||
|
|
@ -756,7 +760,7 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
|
|||
* is invalid.
|
||||
*/
|
||||
if ((ret < 0) ||
|
||||
(!is_valid_ether_addr(&enet_addr[i * 6]))) {
|
||||
(!is_valid_ethaddr(&enet_addr[i * 6]))) {
|
||||
memcpy(&dev[i]->enetaddr[0], ipq_def_enetaddr, 6);
|
||||
dev[i]->enetaddr[5] = gmac_cfg->unit & 0xff;
|
||||
} else {
|
||||
|
|
@ -850,12 +854,19 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
|
|||
if (bb_nodes[i] == NULL)
|
||||
goto failed;
|
||||
memset(bb_nodes[i], 0, sizeof(struct bitbang_nodes));
|
||||
bb_nodes[i]->mdio = gboard_param->gmac_gpio[0].gpio;
|
||||
bb_nodes[i]->mdc = gboard_param->gmac_gpio[1].gpio;
|
||||
bb_miiphy_buses[i].priv = bb_nodes[i];
|
||||
strncpy(bb_miiphy_buses[i].name, gmac_cfg->phy_name,
|
||||
sizeof(bb_miiphy_buses[i].name));
|
||||
miiphy_register(bb_miiphy_buses[i].name, bb_miiphy_read, bb_miiphy_write);
|
||||
|
||||
gmac_gpio_node = fdt_path_offset(gd->fdt_blob, "/gmac/gmac_gpio");
|
||||
if (gmac_gpio_node >= 0) {
|
||||
offset = fdt_first_subnode(gd->fdt_blob, gmac_gpio_node);
|
||||
bb_nodes[i]->mdio = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
|
||||
|
||||
offset = fdt_next_subnode(gd->fdt_blob, offset);
|
||||
bb_nodes[i]->mdc = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
|
||||
bb_miiphy_buses[i].priv = bb_nodes[i];
|
||||
strncpy(bb_miiphy_buses[i].name, gmac_cfg->phy_name,
|
||||
sizeof(bb_miiphy_buses[i].name));
|
||||
miiphy_register(bb_miiphy_buses[i].name, bb_miiphy_read, bb_miiphy_write);
|
||||
}
|
||||
|
||||
eth_register(dev[i]);
|
||||
|
||||
|
|
@ -871,9 +882,9 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
|
|||
|
||||
/* set the mac address in environment for unconfigured GMAC */
|
||||
if (ret >= 0) {
|
||||
for (; i < IPQ_GMAC_NMACS; i++) {
|
||||
for (; i < CONFIG_IPQ_NO_MACS; i++) {
|
||||
mac_addr = &enet_addr[i * 6];
|
||||
if (is_valid_ether_addr(mac_addr)) {
|
||||
if (is_valid_ethaddr(mac_addr)) {
|
||||
/*
|
||||
* U-Boot uses these to patch the 'local-mac-address'
|
||||
* dts entry for the ethernet entries, which in turn
|
||||
|
|
@ -889,11 +900,18 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
|
|||
}
|
||||
}
|
||||
|
||||
if (gboard_param->ar8033_gpio) {
|
||||
ar8033_gpio_node = fdt_path_offset(gd->fdt_blob, "/ar8033_gpio");
|
||||
|
||||
if (ar8033_gpio_node != 0) {
|
||||
bb_nodes[i] = malloc(sizeof(struct bitbang_nodes));
|
||||
memset(bb_nodes[i], 0, sizeof(struct bitbang_nodes));
|
||||
bb_nodes[i]->mdio = gboard_param->ar8033_gpio[0].gpio;
|
||||
bb_nodes[i]->mdc = gboard_param->ar8033_gpio[1].gpio;
|
||||
|
||||
offset = fdt_first_subnode(gd->fdt_blob, ar8033_gpio_node);
|
||||
bb_nodes[i]->mdio = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
|
||||
|
||||
offset = fdt_next_subnode(gd->fdt_blob, offset);
|
||||
bb_nodes[i]->mdc = fdtdec_get_uint(gd->fdt_blob, offset, "gpio", 0);
|
||||
|
||||
bb_miiphy_buses[i].priv = bb_nodes[i];
|
||||
strncpy(bb_miiphy_buses[i].name, "8033",
|
||||
sizeof(bb_miiphy_buses[i].name));
|
||||
|
|
@ -903,7 +921,7 @@ int ipq_gmac_init(ipq_gmac_board_cfg_t *gmac_cfg)
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
for (i = 0; i < IPQ_GMAC_NMACS; i++) {
|
||||
for (i = 0; i < CONFIG_IPQ_NO_MACS; i++) {
|
||||
if (bb_nodes[i])
|
||||
free(bb_nodes[i]);
|
||||
if (dev[i]) {
|
||||
|
|
@ -1006,11 +1024,20 @@ static int ipq_eth_bb_init(struct bb_miiphy_bus *bus)
|
|||
static int ipq_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
|
||||
{
|
||||
struct bitbang_nodes *bb_node = bus->priv;
|
||||
struct qca_gpio_config gmac_gpio_config = {0};
|
||||
|
||||
gpio_tlmm_config(bb_node->mdio, 0,
|
||||
GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, 1);
|
||||
gpio_tlmm_config(bb_node->mdc, 0,
|
||||
GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, 1);
|
||||
gmac_gpio_config.gpio = bb_node->mdio;
|
||||
gmac_gpio_config.func = 0;
|
||||
gmac_gpio_config.out = GPIO_OUTPUT;
|
||||
gmac_gpio_config.pull = GPIO_NO_PULL;
|
||||
gmac_gpio_config.drvstr = GPIO_8MA;
|
||||
gmac_gpio_config.oe = 1;
|
||||
|
||||
gpio_tlmm_config(&gmac_gpio_config);
|
||||
|
||||
gmac_gpio_config.gpio = bb_node->mdc;
|
||||
|
||||
gpio_tlmm_config(&gmac_gpio_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1018,12 +1045,23 @@ static int ipq_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
|
|||
static int ipq_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
|
||||
{
|
||||
struct bitbang_nodes *bb_node = bus->priv;
|
||||
struct qca_gpio_config gmac_gpio_config = {0};
|
||||
|
||||
gpio_tlmm_config(bb_node->mdio, 0,
|
||||
GPIO_INPUT, GPIO_NO_PULL, GPIO_8MA, 0);
|
||||
gpio_tlmm_config(bb_node->mdc, 0,
|
||||
GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, 1);
|
||||
gmac_gpio_config.gpio = bb_node->mdio;
|
||||
gmac_gpio_config.func = 0;
|
||||
gmac_gpio_config.out = GPIO_INPUT;
|
||||
gmac_gpio_config.pull = GPIO_NO_PULL;
|
||||
gmac_gpio_config.drvstr = GPIO_8MA;
|
||||
gmac_gpio_config.oe = 0;
|
||||
|
||||
gpio_tlmm_config(&gmac_gpio_config);
|
||||
|
||||
|
||||
gmac_gpio_config.gpio = bb_node->mdc;
|
||||
gmac_gpio_config.out = GPIO_OUTPUT;
|
||||
gmac_gpio_config.oe = 1;
|
||||
|
||||
gpio_tlmm_config(&gmac_gpio_config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1106,7 +1144,7 @@ static int ipq_eth_unregister(void)
|
|||
int i;
|
||||
struct eth_device *dev;
|
||||
|
||||
for (i = 0; i < IPQ_GMAC_NMACS; i++) {
|
||||
for (i = 0; i < CONFIG_IPQ_NO_MACS; i++) {
|
||||
if (bb_nodes[i])
|
||||
free(bb_nodes[i]);
|
||||
if (ipq_gmac_macs[i]) {
|
||||
|
|
@ -1132,7 +1170,7 @@ static int do_force_eth_speed(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
if (argc != 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
ipq_gmac_board_cfg_t *gmac_tmp_cfg = gboard_param->gmac_cfg;
|
||||
ipq_gmac_board_cfg_t *gmac_tmp_cfg = gmac_cfg;
|
||||
|
||||
if (strict_strtoul(argv[1], 16, (unsigned long *)&phy_addr) < 0) {
|
||||
ipq_info("Invalid Phy addr configured\n");
|
||||
|
|
@ -1167,7 +1205,7 @@ static int do_force_eth_speed(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
get_params.is_forced = 1;
|
||||
get_params.miiwrite_done = 1;
|
||||
ipq_eth_unregister();
|
||||
status = ipq_gmac_init(gboard_param->gmac_cfg);
|
||||
status = ipq_gmac_init(gmac_cfg);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
* All definitions in this file are operating system independent!
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <miiphy.h>
|
||||
#include <asm/arch-ipq806x/athrs17_phy.h>
|
||||
#include <asm/arch-ipq806x/qca8511.h>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue