375 lines
9.5 KiB
Diff
375 lines
9.5 KiB
Diff
--- a/arch/arm/kernel/setup.c
|
|
+++ b/arch/arm/kernel/setup.c
|
|
@@ -31,7 +31,18 @@
|
|
#include <linux/bug.h>
|
|
#include <linux/compiler.h>
|
|
#include <linux/sort.h>
|
|
+
|
|
+#ifdef CONFIG_GMAC_FOR_BANANAPI
|
|
+#include <linux/types.h>
|
|
+#include <linux/device.h>
|
|
+#include <linux/platform_device.h>
|
|
#include <linux/io.h>
|
|
+#include <linux/mii.h>
|
|
+#include <linux/phy.h>
|
|
+#include <linux/clk.h>
|
|
+#endif
|
|
+
|
|
+
|
|
|
|
#include <asm/unified.h>
|
|
#include <asm/cp15.h>
|
|
@@ -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 <mach/gpio.h>
|
|
#include <mach/irqs.h>
|
|
#include <mach/clock.h>
|
|
+#ifdef CONFIG_GMAC_FOR_BANANAPI
|
|
+#include <mach/includes.h>
|
|
+#include <plat/sys_config.h> //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 <linux/gpio.h>
|
|
|
|
#include <plat/sys_config.h>
|
|
-#include <plat/platform.h>
|
|
#include <mach/gpio.h>
|
|
#include <mach/clock.h>
|
|
|
|
@@ -51,6 +50,10 @@
|
|
#include "gmac_desc.h"
|
|
#include "gmac_ethtool.h"
|
|
|
|
+#ifdef CONFIG_GMAC_FOR_BANANAPI
|
|
+#include <plat/platform.h>
|
|
+#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;
|