/*****************************************************************************
* I.MX6 Ar8031 device register hacking
* 声明:
* 主要是为了知道网卡的注册流程,如果需要对网卡中的一些需求进行修改时,能够
* 能够快速的对需求进行分析、修改。
*
* 2015-8-15 雨 深圳 南山区平山村 曾剑锋
****************************************************************************/ /*
* initialize __mach_desc_MX6Q_SABRESD data structure.
*/
MACHINE_START(MX6Q_SABRESD, "Freescale i.MX 6Quad/DualLite/Solo Sabre-SD Board")
/* Maintainer: Freescale Semiconductor, Inc. */
.boot_params = MX6_PHYS_OFFSET + 0x100,
.fixup = fixup_mxc_board,
.map_io = mx6_map_io,
.init_irq = mx6_init_irq,
.init_machine = mx6_sabresd_board_init, ------------+
.timer = &mx6_sabresd_timer, |
.reserve = mx6q_sabresd_reserve, |
MACHINE_END |
|
/*! |
* Board specific initialization. |
*/ |
static void __init mx6_sabresd_board_init(void) <-----+
{
......
imx6_init_fec(fec_data); -----------------------------------------------+
...... | |
} +-------------+ |
| |
/*SBC-7112 NET Driver*/ V |
static struct fec_platform_data fec_data __initdata = { |
.init = mx6q_sabresd_fec_phy_init, -----+ |
.power_hibernate = mx6_sabresd_fec_power_hibernate,--*------+|
.phy = PHY_INTERFACE_MODE_RGMII, | ||
#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO | ||
.gpio_irq = MX6_ENET_IRQ, | ||
#endif | ||
}; | ||
| ||
static int mx6q_sabresd_fec_phy_init(struct phy_device *phydev) <---+ ||
{ ||
unsigned short val; ||
gpio_request(SABRESD_FEC_PHY_RESET,"phy-rst"); ||
gpio_direction_output(SABRESD_FEC_PHY_RESET, ); ||
mdelay(); ||
gpio_direction_output(SABRESD_FEC_PHY_RESET, ); ||
mdelay(); ||
gpio_direction_output(SABRESD_FEC_PHY_RESET, ); ||
mdelay(); ||
||
/* Ar8031 phy SmartEEE feature cause link status generates glitch, ||
* which cause ethernet link down/up issue, so disable SmartEEE ||
*/ ||
phy_write(phydev, 0xd, 0x3); ||
phy_write(phydev, 0xe, 0x805d); ||
phy_write(phydev, 0xd, 0x4003); ||
val = phy_read(phydev, 0xe); ||
val &= ~(0x1 << ); ||
phy_write(phydev, 0xe, val); ||
||
/* To enable AR8031 ouput a 125MHz clk from CLK_25M */ ||
phy_write(phydev, 0xd, 0x7); ||
phy_write(phydev, 0xe, 0x8016); ||
phy_write(phydev, 0xd, 0x4007); ||
val = phy_read(phydev, 0xe); ||
||
val &= 0xffe3; ||
val |= 0x18; ||
phy_write(phydev, 0xe, val); ||
||
/* introduce tx clock delay */ ||
phy_write(phydev, 0x1d, 0x5); ||
val = phy_read(phydev, 0x1e); ||
val |= 0x0100; ||
phy_write(phydev, 0x1e, val); ||
||
/*check phy power*/ ||
val = phy_read(phydev, 0x0); ||
if (val & BMCR_PDOWN) ||
phy_write(phydev, 0x0, (val & ~BMCR_PDOWN)); --------+ ||
return ; | ||
} +------------------------------------+ ||
V ||
static inline void phy_write(struct mii_phy *phy, int reg, int val) ||
{ ||
phy->mdio_write(phy->dev, phy->address, reg, val); ||
} ||
||
static int mx6_sabresd_fec_power_hibernate(struct phy_device *phydev) <---+|
{ |
unsigned short val; |
|
/*set AR8031 debug reg 0xb to hibernate power*/ |
phy_write(phydev, 0x1d, 0xb); |
val = phy_read(phydev, 0x1e); |
|
val |= 0x8000; |
phy_write(phydev, 0x1e, val); |
|
return ; |
} |
|
void __init imx6_init_fec(struct fec_platform_data fec_data) <---------+
{
fec_get_mac_addr(fec_data.mac); --------+
if (!is_valid_ether_addr(fec_data.mac)) --------*-----------------------+
random_ether_addr(fec_data.mac); --------*----------------------+|
| ||
if (cpu_is_mx6sl()) | ||
imx6sl_add_fec(&fec_data); | ||
else | ||
imx6q_add_fec(&fec_data); --------*---------------------+||
} | |||
| |||
static int fec_get_mac_addr(unsigned char *mac) <----+ |||
{ |||
unsigned int value; |||
|||
value = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + HW_OCOTP_MACn()); |||
printk("<danny debug> vaule = %x\n",value); |||
value = 0x03040506; |||
mac[] = value & 0xff; |||
mac[] = (value >> ) & 0xff; |||
mac[] = (value >> ) & 0xff; |||
mac[] = (value >> ) & 0xff; |||
value = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + HW_OCOTP_MACn()); |||
printk("<danny debug> vaule = %x\n",value); |||
value = 0x0102; |||
mac[] = value & 0xff; |||
mac[] = (value >> ) & 0xff; |||
|||
return ; |||
} |||
|||
static inline int is_valid_ether_addr(const u8 *addr) <------------**+
{ ||
/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to ||
* explicitly check for it here. */ ||
return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); ||
} ^ V ||
V | ||
static inline int is_multicast_ether_addr(const u8 *addr) | ||
{ | ||
return 0x01 & addr[]; | ||
} | ||
| ||
static inline int is_zero_ether_addr(const u8 *addr) <-----+ ||
{ ||
return !(addr[] | addr[] | addr[] | addr[] | addr[] | addr[]); ||
} ||
||
static inline void random_ether_addr(u8 *addr) <--------------------*+
{ |
get_random_bytes (addr, ETH_ALEN); -----------------------+ |
addr [] &= 0xfe; /* clear multicast bit */ | |
addr [] |= 0x02; /* set local assignment bit (IEEE802) */ | |
} | |
| |
void get_random_bytes(void *buf, int nbytes) <--------------+ |
{ |
extract_entropy(&nonblocking_pool, buf, nbytes, , ); -----------+ |
} | |
EXPORT_SYMBOL(get_random_bytes); | |
| |
/********************************************************************* | |
* | |
* Entropy extraction routines | |
* | |
********************************************************************/ | |
| |
static ssize_t extract_entropy(struct entropy_store *r, void *buf, <--+ |
size_t nbytes, int min, int rsvd); |
|
extern const struct imx_fec_data imx6q_fec_data __initconst; ------+ |
#define imx6q_add_fec(pdata) \ <----------------------*-------+
imx_add_fec(&imx6q_fec_data, pdata) -----------*----+
| |
#ifdef CONFIG_SOC_IMX6Q | |
const struct imx_fec_data imx6q_fec_data __initconst = <---------+ |
imx_fec_data_entry_single(MX6Q, "enet"); -----+ |
| |
const struct imx_fec_data imx6sl_fec_data __initconst = | |
imx_fec_data_entry_single(MX6DL, "fec"); | |
#endif | |
| |
#define imx_fec_data_entry_single(soc, _devid) \ <----+ |
{ \ |
.iobase = soc ## _FEC_BASE_ADDR, \ |
.irq = soc ## _INT_FEC, \ |
.devid = _devid, \ |
} |
|
struct platform_device *__init imx_add_fec( <----------------------+
const struct imx_fec_data *data,
const struct fec_platform_data *pdata)
{
struct resource res[] = {
{
.start = data->iobase,
.end = data->iobase + SZ_4K - ,
.flags = IORESOURCE_MEM,
}, {
.start = data->irq,
.end = data->irq,
.flags = IORESOURCE_IRQ,
},
}; if (!fuse_dev_is_available(MXC_DEV_ENET)) ------+
return ERR_PTR(-ENODEV); |
|
return imx_add_platform_device_dmamask(data->devid, , --*-----+
res, ARRAY_SIZE(res), | |
pdata, sizeof(*pdata), DMA_BIT_MASK()); | |
} | |
| |
int fuse_dev_is_available(enum mxc_dev_type dev) <-----+ |
{ |
...... |
if (!cpu_is_mx6()) |
return ; |
|
/* mx6sl is still not supported */ |
if (cpu_is_mx6sl()) |
return ; |
|
switch (dev) { |
case MXC_DEV_PXP: |
if (cpu_is_mx6q()) |
return ; |
|
if (cpu_is_mx6dl()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x80000000; |
} |
break; |
case MXC_DEV_OVG: |
if (cpu_is_mx6dl()) |
return ; |
|
if (cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x40000000; |
} |
break; |
case MXC_DEV_DSI_CSI2: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x10000000; |
} |
break; |
case MXC_DEV_ENET: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x08000000; |
} |
break; |
case MXC_DEV_MLB: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x04000000; |
} |
break; |
case MXC_DEV_EPDC: |
if (cpu_is_mx6q()) |
return ; |
|
if (cpu_is_mx6dl()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x02000000; |
} |
break; |
case MXC_DEV_HDMI: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000080; |
} |
break; |
case MXC_DEV_PCIE: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000040; |
} |
break; |
case MXC_DEV_SATA: |
if (cpu_is_mx6dl()) |
return ; |
|
if (cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000020; |
} |
break; |
case MXC_DEV_DTCP: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000010; |
} |
break; |
case MXC_DEV_2D: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000008; |
} |
break; |
case MXC_DEV_3D: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000004; |
} |
break; |
case MXC_DEV_VPU: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00008000; |
} |
break; |
case MXC_DEV_DIVX3: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000400; |
} |
break; |
case MXC_DEV_RV: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000200; |
} |
break; |
case MXC_DEV_SORENSEN: |
if (cpu_is_mx6dl() || cpu_is_mx6q()) { |
reg = HW_OCOTP_CFGn(); |
mask = 0x00000100; |
} |
break; |
default: |
/* we treat the unkown device is avaiable by default */ |
return ; |
} |
|
ret = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + reg) & mask; |
pr_debug("fuse_check: %s is %s\n", names[dev], ret ? |
"unavailable" : "available"); |
|
return !ret; |
} +-------------------------+
V
struct platform_device *__init imx_add_platform_device_dmamask(
const char *name, int id,
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data, u64 dmamask)
{
int ret = -ENOMEM;
struct platform_device *pdev; pdev = platform_device_alloc(name, id);
if (!pdev)
goto err; if (dmamask) {
/*
* This memory isn't freed when the device is put,
* I don't have a nice idea for that though. Conceptually
* dma_mask in struct device should not be a pointer.
* See http://thread.gmane.org/gmane.linux.kernel.pci/9081
*/
pdev->dev.dma_mask =
kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
if (!pdev->dev.dma_mask)
/* ret is still -ENOMEM; */
goto err; *pdev->dev.dma_mask = dmamask;
pdev->dev.coherent_dma_mask = dmamask;
} if (res) {
ret = platform_device_add_resources(pdev, res, num_resources);
if (ret)
goto err;
} if (data) {
ret = platform_device_add_data(pdev, data, size_data);
if (ret)
goto err;
} ret = platform_device_add(pdev);
if (ret) {
err:
if (dmamask)
kfree(pdev->dev.dma_mask);
platform_device_put(pdev);
return ERR_PTR(ret);
} return pdev;
}

I.MX6 Ar8031 device register hacking的更多相关文章

  1. I.MX6 Power off register hacking

    /*********************************************************************** * I.MX6 Power off register ...

  2. OK335xS GPMC nand device register hacking

    /********************************************************************************* * OK335xS GPMC na ...

  3. OK335xS pwm device register hacking

    /************************************************************************* * OK335xS pwm device regi ...

  4. I.MX6 ar1020 SPI device driver hacking

    /************************************************************************************ * I.MX6 ar1020 ...

  5. I.MX6 Linux I2C device& driver hacking

    /******************************************************************************************* * I.MX6 ...

  6. OK335xS CAN device register and deiver match hacking

    /************************************************************************* * OK335xS CAN device regi ...

  7. I.MX6 AD7606-4 device driver registe hacking

    /********************************************************************** * I.MX6 AD7606-4 device driv ...

  8. I.MX6 AR8031 寄存器操作

    /*************************************************************************** * I.MX6 AR8031 寄存器操作 * ...

  9. I.MX6 PWM buzzer driver hacking with Demo test

    /***************************************************************************** * I.MX6 PWM buzzer dr ...

随机推荐

  1. Windows系统下在Eclipse中集成Python

    我现在偶尔开发代码,已经不用Eclipse了,主要原因是查看Jar包中的代码反编译十分不便,项目加载的时候卡,偶尔还会崩溃 用Intellij IDEA和PyCharm 原来的笔记如何在Eclipse ...

  2. Codeforces 916C - Jamie and Interesting Graph

    916C - Jamie and Interesting Graph 思路:构造. 对于1到n最短路且素数,那么1到n之间连2 对于最小生成树,找一个稍微大点的素数(比1e5大)构造一个和为这个素数的 ...

  3. angular5 ng-content使用方法

    先自定义一个组件import { Component } from '@angular/core'; @Component({ selector: 'exe-greet', template: ` & ...

  4. getpagesize.c:32: __getpagesize: Assertion `_rtld_global_ro._dl_pagesize != 0' failed

    为arm 编译 mysql , 执行的时候出现了这个问题. 好像是个bug, https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=626379 重新编译 ...

  5. 20161208xlVBA工作表数据导入Access

    Sub InsertToDataBase() Dim DataPath As String Dim SQL As String Const DataName As String = "yun ...

  6. sgu 126 Boxes

    题意:较大的容量减较小的容量,较小的容量翻倍.问操作几回其中一个空. 开始用set判重,重复就不可行.不过状态最多有2e18种.不仅爆内存,还超时.然后找规律.发现只有比例为1:1,1:3,1:7,3 ...

  7. Sonya and Ice Cream CodeForces - 1004E 树的直径, 贪心

    题目链接 set维护最小值贪心, 刚开始用树的直径+单调队列没调出来... #include <iostream>#include <cstdio> #include < ...

  8. Ciel the Commander CodeForces - 321C (树, 思维)

    链接 大意: 给定n结点树, 求构造一种染色方案, 使得每个点颜色在[A,Z], 且端点同色的链中至少存在一点颜色大于端点 (A为最大颜色) 直接点分治即可, 因为最坏可以涂$2^{26}-1$个节点 ...

  9. laravel command

    (1) 新建一个command类,并在command类里面写相应的执行函数 其中变量act就是指函数名,handle里面会先判断该函数是不是存在,如果存在就执行,如果不存在就提示函数不存在 class ...

  10. Hadoop生产环境搭建(含HA、Federation)

    Hadoop生产环境搭建 1. 将安装包hadoop-2.x.x.tar.gz存放到某一目录下,并解压. 2. 修改解压后的目录中的文件夹etc/hadoop下的配置文件(若文件不存在,自己创建.) ...