/*****************************************************************************
* 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. wc的使用

    统计文件个数 ls -l |grep "^-"|wc -l 统计目录的个数 ls -l|grep "^d"|wc -l 统计文件个数(包括子文件夹) ls -l ...

  2. 如何上传本地文件到github又如何删除自己的github仓库

    首先自己在https://github.com/网站要注册一个账户 自己上传工程到jithub,没有付费的用户只能选用public,意味着你的项目在全网是可以被看到和下载的: 所以涉及私密信息的,需要 ...

  3. java动态代理和cglib

    1.代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建而成. 2.JD ...

  4. ZC_C++类函数指针_模拟_Delphi类函数指针

    ZC: C++的类函数指针 不像 Delphi的类函数指针,前者 需要规定死 是哪个类的函数的指针,后者就不需要 很灵活. 测试环境: Win7x64 cn_visual_studio_2010_ul ...

  5. Codeforces 197D - Infinite Maze

    197D - Infinite Maze 思路:bfs,如果一个点被搜到第二次,那么就是符合要求的. 用vis[i][j].x,vis[i][j].y表示i,j(i,j是取模过后的值)这个点第一次被搜 ...

  6. ubuntu16.04 安装NVIDIA和CUDA9.2 cudNN7.1

    1.安装NVIDIA驱动 (1)查询NVIDIA驱动 首先去官网(http://www.nvidia.com/Download/index.aspx?lang=en-us)查看适合自己显卡的驱动(下载 ...

  7. Vue.js教程--基础(实例 模版语法template computed, watch v-if, v-show v-for, 一个组件的v-for.)

    官网:https://cn.vuejs.org/v2/guide/index.html Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统. 视频教程:https: ...

  8. homestead 暴露接口到外网

    laravel 官方推荐的运行环境是homestead,但homestead是个虚拟机,你自己访问没问题,给别人联调怎么办? 一个大型项目肯定不止一个人开发,这个时候就需要将你虚拟机上的接口暴露给外网 ...

  9. ubuntu修改root密码

    1.我们在安装系统的时候我们会把系统的密码设置的比较简单,所以导致后面我们别人很容易操作我们的电脑.所以,我们就可以修改密码,你只要在系统上输入: sudo passwd root

  10. thinkphp if标签

    1.thinkphp框架中的if标签,用于html页面中.在html中编写php代码 1).从控制器中得到数据在循环中if else 判断:<volist name="system_r ...