Exynos4412 移植针对Samsung的Linux-6.1(五)DM9000网卡驱动

系列文章目录


Exynos4412 移植针对Samsung的Linux-6.1(五)DM9000网卡驱动

前言:Linux-6.1对DM9000网卡是支持的,但是设备树的写法与Linux-5.4的写法不同。

1、不成功的设备树写法

刚开始编写设备树的时候,内核启动时始终无法加载DM9000驱动。如果把eth的compatible改成“simple-bus”,就能够加载驱动,但是不一定是DM9000的驱动。以下是不成功的DM9000设备树写法:

    memory-controller@12570000 {
        #address-cells = <2>;
        #size-cells = <1>;
        ranges = <0 0 0x04000000 0x20000   // Bank0
              1 0 0x05000000 0x20000   // Bank1
              2 0 0x06000000 0x20000   // Bank2
              3 0 0x07000000 0x20000>; // Bank3

        ethernet@1,0{
            compatible = "davicom,dm9000";
            reg = <1 0 0x2 1 4 0x2>;
            interrupt-parent = <&gpx0>;    
            interrupts = <7 IRQ_TYPE_EDGE_RISING>; 
            samsung,srom-page-mode;// normal(1data)page mode configuration
            samsung,srom-timing = <9 12 1 5 1 1>; 
            davicom,no-eeprom;
            mac-address = [00 0c 29 d3 fe 1d];
        };  
    }; 

DM9000A的中断请求INT信号,是高电平有效,不是上升沿有效.
include/dt-bindings/interrupt-controller/irq.h定义了中断类型的宏定义

#define IRQ_TYPE_NONE		0
#define IRQ_TYPE_EDGE_RISING	1
#define IRQ_TYPE_EDGE_FALLING	2
#define IRQ_TYPE_EDGE_BOTH	(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
#define IRQ_TYPE_LEVEL_HIGH	4
#define IRQ_TYPE_LEVEL_LOW	8

2、成功的设备树写法

后来看到有博文解释,当device与driver相匹配时,最终会调用drivers/base/dd.c中的really_probe()函数。那么,可以在该函数中添加printk,或者定义宏DEBUG(内核源码include/printk.h文件定义了pr_debug),来跟踪打印显示有哪些device被注册。通过这个方法发现,以上设备树的写法,DM9000的驱动和设备没有匹配,压根就没有注册DM9000的驱动,所以更换成为以下设备树写法。内核启动时,就可以发现DM9000了。成功的设备树写法如下:

/dts-v1/;
#include "exynos4.dtsi"
#include "exynos4412.dtsi"
#include "exynos4412-pinctrl.dtsi"
#include <dt-bindings/clock/exynos4.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "exynos-pinctrl.h"
#include <dt-bindings/interrupt-controller/arm-gic.h>

/ {
    model = "CBT4412 board based on Exynos4412";
    compatible = "samsung,exynos4412";

    chosen {
        stdout-path = &serial_0;
    };

    aliases{
        serial0 = "/serial@13800000";
        serial1 = "/serial@13800020";
        console = "/serial@13800000";
        mmc1 = "/mmc@12530000";
        mmc2 = "/&mshc_0";
    };

	memctrl:memory-controller@12570000 {
        #address-cells = <2>;
        #size-cells = <1>;
        ranges = <0 0 0x04000000 0x20000   // Bank0
              1 0 0x05000000 0x20000   // Bank1
              2 0 0x06000000 0x20000   // Bank2
              3 0 0x07000000 0x20000>; // Bank3
        pinctrl-0 = <&srom_ctrl1 &srom_ctrl2 &ebi_data1 &ebi_data2>;
        pinctrl-name = "default";
        eth@1,0{
            reg = <1 0 0x2 1 4 0x2>;
            samsung,srom-page-mode;// normal(1data)page mode configuration
            samsung,srom-timing = <9 12 1 5 1 1>;
            davicom,no-eeprom;
            mac-address = [00 0c 29 d3 fe 1d];
            };
        };

    memory@40000000 {
        device_type = "memory";
        reg = <0x40000000 0x40000000>;
    };

    fixed-rate-clocks {
        xxti {
            compatible = "samsung,clock-xxti";
            clock-frequency = <0>;
        };

        xusbxti {
            compatible = "samsung,clock-xusbxti";
            clock-frequency = <24000000>;
        };
    };
    
	ethernet@50000000{
            compatible = "davicom,dm9000";
            reg = <0x5000000 0x02 0x5000004 0x2>;
            interrupt-parent = <&gpx0>;
            interrupts = <7 IRQ_TYPE_EDGE_RISING>;
            samsung,srom-page-mode;// normal(1data)page mode configuration
            samsung,srom-timing = <9 12 1 5 1 1>;
            davicom,no-eeprom;
            mac-address = [00 0c 29 d3 fe 1d];
            pinctrl-0 = <&srom_ctrl1 &srom_ctrl2 &ebi_data1 &ebi_data2>;
            pinctrl-name = "default";
	};
};

&gpy0 {
            srom_ctrl1:srom_ctrl1{
                samsung,pins = "gpy0-1","gpy0-4","gpy0-5";
                samsung,pin-function = <2>; /*samsung,pin-function = <EXYNOS_PIN_FUNC_2>;*/
                samsung,pin-pud = <0>;
                samsung,pin-drv = <3>;
            };  
};

&gpy1 {
            srom_ctrl2:srom_ctrl2{
                samsung,pins = "gpy1-0","gpy1-1","gpy1-2","gpy1-3";
                samsung,pin-function = <2>; /*samsung,pin-function = <EXYNOS_PIN_FUNC_2>;*/
                samsung,pin-pud = <0>;
                samsung,pin-drv = <3>;
            };  
};

&gpy5 {
            ebi_data1:ebi_data1{
                samsung,pins = "gpy5-0","gpy5-1","gpy5-2","gpy5-3","gpy5-4","gpy5-5","gpy5-6","gpy5-7";
                samsung,pin-function = <2>; /*samsung,pin-function = <EXYNOS_PIN_FUNC_2>;*/
                samsung,pin-pud = <0>;
                samsung,pin-drv = <3>;
            };  
    };  
    
&gpy6 {
            ebi_data2:ebi_data2{
                samsung,pins = "gpy6-0","gpy6-1","gpy6-2","gpy6-3","gpy6-4","gpy6-5","gpy6-6","gpy6-7";
                samsung,pin-function = <2>; /*samsung,pin-function = <EXYNOS_PIN_FUNC_2>;*/
                samsung,pin-pud = <0>;
                samsung,pin-drv = <3>;
            };
    };

&serial_0 {
    status = "okay";
};

3、exynos-srom.c中的BUG

drivers/memory/samsung/exynos-srom.c中的exynos_srom_probe()函数是有BUG的。该函数会给4个bank配置参数。这是通过include/linux/of.h中的宏for_each_child_of_node(parent, child)来实现。但是,这个宏在实际调用中报错,错误的原因是child的指针是NULL。

#define for_each_child_of_node(parent, child) \
	for (child = of_get_next_child(parent, NULL); child != NULL; \
	     child = of_get_next_child(parent, child))
#define for_each_node_by_name(dn, name) \
	for (dn = of_find_node_by_name(NULL, name); dn; \
	     dn = of_find_node_by_name(dn, name))

我采用的方法是把for_each_child_of_node(np, child)改成for_each_node_by_name(child,“eth”)。当然,这个方法具有局限性,如果name不是eth,那么就不正确了。如果您有更好的方法,请在留言区讨论留言。
另外,实际的应用中,并不需要exynos_srom_probe()函数来初始化SROMC的参数,因为u-boot启动过程中,就已经初始化了。

参考文献:
DM9000驱动解析_xiyu_1986的博客-CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值