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:
Aditya Kumar Patra S 2016-09-26 16:38:36 +05:30 committed by Gerrit - the friendly Code Review server
parent 84d2f385fb
commit 2c97e2ff04
5 changed files with 150 additions and 45 deletions

View file

@ -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 */

View file

@ -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

View file

@ -272,9 +272,9 @@ int do_ar8xxx_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
struct athrs17_regmap *section = &regmap[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);
}
}

View file

@ -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;
}

View file

@ -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>