--- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -31,7 +31,18 @@ #include #include #include + +#ifdef CONFIG_GMAC_FOR_BANANAPI +#include +#include +#include #include +#include +#include +#include +#endif + + #include #include @@ -1101,16 +1112,13 @@ seq_printf(m, "Hardware\t: %s\n", machine_name); seq_printf(m, "Revision\t: %04x\n", system_rev); +#ifdef CONFIG_GMAC_FOR_BANANAPI + seq_printf(m, "Serial\t\t: %08x%08x%08x%08x\n", readl(SW_VA_SID_IO_BASE+0x0C), + readl(SW_VA_SID_IO_BASE+0x08), readl(SW_VA_SID_IO_BASE+0x04), readl(SW_VA_SID_IO_BASE)); +#else seq_printf(m, "Serial\t\t: %08x%08x\n", system_serial_high, system_serial_low); - - #define SW_VA_SID_IO_BASE 0xf1c23800 - seq_printf(m, "Chipid\t\t: %08x-%08x-%08x-%08x\n", - readl(SW_VA_SID_IO_BASE), - readl(SW_VA_SID_IO_BASE + 0x4), - readl(SW_VA_SID_IO_BASE + 0x8), - readl(SW_VA_SID_IO_BASE + 0xc) - ); +#endif return 0; } --- a/arch/arm/plat-sunxi/sys_config.c +++ b/arch/arm/plat-sunxi/sys_config.c @@ -145,6 +145,7 @@ return gpio_count; } +EXPORT_SYMBOL(script_parser_mainkey_get_gpio_count); //Fix the GAMC cannot build as module int script_parser_mainkey_get_gpio_cfg(char *main_name, void *gpio_cfg, int gpio_count) { @@ -179,6 +180,7 @@ return SCRIPT_PARSER_KEY_NOT_FIND; } +EXPORT_SYMBOL(script_parser_mainkey_get_gpio_cfg); //Fix the GAMC cannot build as module /* * --- a/drivers/net/ethernet/allwinner/gmac/sunxi_gmac.h +++ b/drivers/net/ethernet/allwinner/gmac/sunxi_gmac.h @@ -33,6 +33,9 @@ #include "gmac_base.h" #define GMAC_RESOURCE_NAME "sunxi_gmac" +#ifdef CONFIG_GMAC_FOR_BANANAPI + #define GMAC_PHY_POWER +#endif enum rx_frame_status { /* IPC status */ good_frame = 0, @@ -132,7 +135,11 @@ void __iomem *gpiobase; #else int gpio_cnt; +#ifdef CONFIG_GMAC_FOR_BANANAPI + user_gpio_set_t *gpio_hd; +#else unsigned int gpio_handle; +#endif #endif #ifndef CONFIG_GMAC_CLK_SYS @@ -163,6 +170,9 @@ spinlock_t lock; spinlock_t tx_lock; struct gmac_plat_data *plat; +#ifdef GMAC_PHY_POWER + u32 gpio_power_hd; +#endif //struct dma_features dma_cap; }; --- a/drivers/net/ethernet/allwinner/gmac/Kconfig +++ b/drivers/net/ethernet/allwinner/gmac/Kconfig @@ -29,6 +29,13 @@ If you want to use the system interface, select it. If not, the driver will control the clock by ioremap. +config GMAC_FOR_BANANAPI + bool "modified gmac driver for Bananapi" + depends on SUNXI_GMAC + ---help--- + If you want to compile the firmware for Bananapi, you should select it. + The driver will be modified to be suit for the Bananapi' gmac. + choice prompt "Select the DMA TX/RX descriptor operating modes" depends on SUNXI_GMAC --- a/drivers/net/ethernet/allwinner/gmac/gmac_plat.c +++ b/drivers/net/ethernet/allwinner/gmac/gmac_plat.c @@ -34,6 +34,10 @@ #include #include #include +#ifdef CONFIG_GMAC_FOR_BANANAPI +#include +#include //Fix the GAMC cannot build as module +#endif #include "sunxi_gmac.h" @@ -43,11 +47,64 @@ int ret = 0; #ifndef CONFIG_GMAC_SCRIPT_SYS +#ifdef CONFIG_GMAC_FOR_BANANAPI + int reg_value; + /* configure system io */ + if(priv->gpiobase){ + writel(0x22222222, priv->gpiobase + PA_CFG0); + + writel(0x22222222, priv->gpiobase + PA_CFG1); + + writel(0x00000022, priv->gpiobase + PA_CFG2); +#else if(priv->gpiobase){ writel(0x55555555, priv->gpiobase + PA_CFG0); writel(0x50555505, priv->gpiobase + PA_CFG1); writel(0x00000005, priv->gpiobase + PA_CFG2); } +#endif +#else +#ifdef CONFIG_GMAC_FOR_BANANAPI + int i = 0; + int gpio_tmp; + + priv->gpio_cnt = script_parser_mainkey_get_gpio_count("gmac_para"); + priv->gpio_hd = kmalloc(sizeof(user_gpio_set_t)*priv->gpio_cnt, GFP_KERNEL); + printk("gmac_para gpio count is %d\n", priv->gpio_cnt); + script_parser_mainkey_get_gpio_cfg("gmac_para", priv->gpio_hd, priv->gpio_cnt); + for (i = 0; i < priv->gpio_cnt; i++){ + gpio_tmp = gpio_request_ex("gmac_para", priv->gpio_hd[i].gpio_name); + if (gpio_tmp){ + gpio_set_one_pin_status(gpio_tmp, &priv->gpio_hd[i], priv->gpio_hd[i].gpio_name, 1); + }else{ + printk("gpio_set_one_pin_status error\n"); + } + } +#ifdef GMAC_PHY_POWER + priv->gpio_power_hd= gpio_request_ex("gmac_phy_power", "gmac_phy_power_en"); +#endif +gpio_err: + if(unlikely(ret)){ + gpio_free(priv->gpio_hd); + priv->gpio_hd = NULL; + priv->gpio_cnt = 0; + } +#ifdef SUN7i_GMAC_FPGA + reg_value = readl(IO_ADDRESS(GPIO_BASE + 0x108)); + reg_value |= 0x1<<20; + writel(reg_value, IO_ADDRESS(GPIO_BASE + 0x108)); + + reg_value = readl(IO_ADDRESS(GPIO_BASE + 0x10c)); + reg_value &= ~(0x1<<29); + writel(reg_value, IO_ADDRESS(GPIO_BASE + 0x10c)); + + mdelay(200); + + reg_value = readl(IO_ADDRESS(GPIO_BASE + 0x10c)); + reg_value |= 0x1<<29; + writel(reg_value, IO_ADDRESS(GPIO_BASE + 0x10c)); +#endif + #else priv->gpio_handle = gpio_request_ex("gmac_para", NULL); if(!priv->gpio_handle) { @@ -55,6 +112,7 @@ ret = -1; } #endif +#endif return ret; } @@ -177,8 +235,17 @@ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); release_mem_region(res->start, resource_size(res)); #else + #ifdef CONFIG_GMAC_FOR_BANANAPI + int i; + if (priv->gpio_hd){ + gpio_free(priv->gpio_hd); + priv->gpio_hd = NULL; + priv->gpio_cnt = 0; + } + #else gpio_release(priv->gpio_handle, 0); #endif +#endif iounmap(priv->gmac_clk_reg); --- a/drivers/net/ethernet/allwinner/gmac/gmac_core.c +++ b/drivers/net/ethernet/allwinner/gmac/gmac_core.c @@ -38,7 +38,6 @@ #include #include -#include #include #include @@ -51,6 +50,10 @@ #include "gmac_desc.h" #include "gmac_ethtool.h" +#ifdef CONFIG_GMAC_FOR_BANANAPI +#include +#endif + #undef GMAC_DEBUG #ifdef GMAC_DEBUG #define DBG(nlevel, klevel, fmt, args...) \ @@ -79,7 +82,8 @@ #define GMAC_ALIGN(x) L1_CACHE_ALIGN(x) #define JUMBO_LEN 9000 -static char *mac_str = ":"; +#define GMAC_MAC_ADDRESS "00:00:00:00:00:00" +static char *mac_str = GMAC_MAC_ADDRESS; module_param(mac_str, charp, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(mac_str, "MAC Address String.(xx:xx:xx:xx:xx:xx)"); @@ -217,6 +221,9 @@ || phy_interface == PHY_INTERFACE_MODE_GMII) priv_clk_reg |= 0x00000002; +#ifdef CONFIG_GMAC_FOR_BANANAPI + priv_clk_reg |= (0x00000003<<10); +#endif writel(priv_clk_reg, priv->gmac_clk_reg + GMAC_CLK_REG); } @@ -773,21 +780,17 @@ static void gmac_check_ether_addr(struct gmac_priv *priv) { + int i; + char *p = mac_str; /* verify if the MAC address is valid, in case of failures it * generates a random MAC address */ if (!is_valid_ether_addr(priv->ndev->dev_addr)) { - if (strlen(mac_str) == 17) { - int i; - char *p = mac_str; - - pr_info("gmac: use mac address from mac_str\n"); - for (i=0; i<6; i++,p++) - priv->ndev->dev_addr[i] = simple_strtoul(p, &p, 16); - } - +#ifdef CONFIG_GMAC_FOR_BANANAPI + gmac_get_umac_addr((void __iomem *) + priv->ndev->base_addr, + priv->ndev->dev_addr, 0); if (!is_valid_ether_addr(priv->ndev->dev_addr)) { unsigned int reg_val; - reg_val = readl(SW_VA_SID_IO_BASE); pr_info("gmac: use mac address from chipid\n"); priv->ndev->dev_addr[0] = 0x02; /* Non OUI / registered MAC address */ @@ -803,12 +806,47 @@ pr_info("gmac: use random mac address\n"); } } - } else { - pr_info("gmac: use mac address from cmdline\n"); +#else + if (!is_valid_ether_addr(priv->ndev->dev_addr)) { + for (i=0; i<6; i++,p++) + priv->ndev->dev_addr[i] = simple_strtoul(p, &p, 16); + } + + if (!is_valid_ether_addr(priv->ndev->dev_addr)) + random_ether_addr(priv->ndev->dev_addr); +#endif + } + printk(KERN_WARNING "%s: device MAC address %pM\n", priv->ndev->name, + priv->ndev->dev_addr); +} + +#ifdef GMAC_PHY_POWER +void gmac_phy_power_en(struct gmac_priv *priv) +{ + if(!priv) return; + + if (priv->gpio_power_hd){ + printk("GMAC gpio_power_hd:gpio_direction_output\n"); + gpio_set_one_pin_io_status(priv->gpio_power_hd, 1, "gmac_phy_power_en");//set the gpio to output + gpio_write_one_pin_value(priv->gpio_power_hd, 1, "gmac_phy_power_en"); + mdelay(200); + } + + return; +} + +void gmac_phy_power_disable(struct gmac_priv *priv) +{ + if(!priv) return; + + if (priv->gpio_power_hd){ + gpio_write_one_pin_value(priv->gpio_power_hd, 0, "gmac_phy_power_en"); } - pr_info("gmac: device MAC address %pM\n", priv->ndev->dev_addr); + return; + } +#endif /** * gmac_open - open entry point of the driver @@ -824,9 +862,14 @@ struct gmac_priv *priv = netdev_priv(ndev); int ret; - gmac_clk_ctl(priv, 1); - //gmac_check_ether_addr(priv); +#ifdef GMAC_PHY_POWER + gmac_phy_power_en(priv); +#endif + gmac_clk_ctl(priv, 1); +#ifdef GMAC_PHY_POWER + gmac_check_ether_addr(priv); +#endif /* MDIO bus Registration */ ret = gmac_mdio_register(ndev); if (ret < 0) { @@ -964,6 +1007,10 @@ gmac_mdio_unregister(ndev); gmac_clk_ctl(priv, 0); +#ifdef GMAC_PHY_POWER + gmac_phy_power_disable(priv); +#endif + return 0; } @@ -1742,6 +1789,9 @@ static void __exit gmac_remove(void) { +#ifdef CONFIG_GMAC_SCRIPT_SYS + script_parser_fetch("gmac_para", "gmac_used", &gmac_used, 1); +#endif if (gmac_used != 1) { pr_info("gmac is disabled\n"); return;