Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)


文章目录

  • Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)
  • 1.出厂源码编译
    • 1 修改顶层 Makefile
    • 2 配置并编译 Linux 内核
    • 3 Linux 内核启动测试
  • 2.移植到自己的arm平台
    • 1 添加开发板默认配置文件
    • 2 添加开发板对应的设备树文件
    • 3 编译测试
  • 3.cpu主频和网络驱动修改
    • 1 CPU 主频修改(无需修改)跳过此节即可
      • 1、设置 I.MX6U-ALPHA 开发板工作在 792MHz
      • 2、超频至 700MHz
    • 2 使能 8 线 EMMC 驱动
    • 3 修改网络驱动
      • 1、修改 LAN8720 的复位以及网络时钟引脚驱动
      • 2、修改 fec1 和 fec2 节点的 pinctrl-0 属性
      • 3、修改 LAN8720A 的 PHY 地址
      • 4、修改 fec_main.c 文件
      • 5、配置 Linux 内核,使能 LAN8720 驱动
      • 6、修改 smsc.c 文件
    • 4 保存修改后的图形化配置文件
      • 1、直接另存为.config 文件
      • 2、通过图形界面保存配置文件
  • 其他修改(重点,参考原子教程移植后依旧有错误,需要按下列内容修改设备树):
    • 原来
    • 最终设备树内容
    • 最终结果
      • 网络驱动测试


nxp出厂Linux源码
https://download.csdn.net/download/weixin_52849254/87663495
移植成功后的Linux源码
https://download.csdn.net/download/weixin_52849254/87659032
NXP 提供的 Linux 源码肯定是可以在自己的 I.MX6ULL EVK 开发板上运行下去的,所以我们肯定是以 I.MX6ULL EVK 开发板为参考,然后将 Linux 内核移植到 I.MX6U-ALPHA 开发板上的。

1.出厂源码编译

1 修改顶层 Makefile

修改顶层 Makefile,直接在顶层 Makefile 文件里面定义 ARCH 和 CROSS_COMPILE 这两个的变量值为 arm 和 arm-linux-gnueabihf-,结果如图所示:
在这里插入图片描述

 252 ARCH        ?= arm
 253 CROSS_COMPILE   ?= arm-linux-gnueabihf-

第 252 和 253 行分别设置了 ARCH 和 CROSS_COMPILE 这两个变量的值,这样在编译的时候就不用输入很长的命令了。

2 配置并编译 Linux 内核

和 uboot 一样,在编译 Linux 内核之前要先配置 Linux 内核。每个板子都有其对应的默认配 置 文 件 , 这 些 默 认 配 置 文 件 保 存 在 arch/arm/configs 目 录 中 。 imx_v7_defconfig 和imx_v7_mfg_defconfig 都可作为 I.MX6ULL EVK 开发板所使用的默认配置文件。但是这里建议使用 imx_v7_mfg_defconfig 这个默认配置文件,首先此配置文件默认支持 I.MX6UL 这款芯片,而且重要的一点就是此文件编译出来的 zImage 可以通过 NXP 官方提供的 MfgTool 工具烧写!!imx_v7_mfg_defconfig 中的“mfg”的意思就是 MfgTool
进入到 Ubuntu 中的 Linux 源码根目录下,执行如下命令配置 Linux 内核:

make clean //第一次编译 Linux 内核之前先清理一下
make imx_v7_mfg_defconfig //配置 Linux 内核

配置完成以后如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第1张图片

配置完成以后就可以编译了,使用如下命令编译 Linux 内核:

make -j16 //编译 Linux 内核

等待编译完成,结果如图所示:
Linux 内核编译完成以后会在 arch/arm/boot 目录下生成 zImage 镜像文件,如果使用设备树的话还会在 arch/arm/boot/dts 目录下开发板对应的.dtb(设备树)文件,比如 imx6ull-14x14-evk.dtb就是 NXP 官方的 I.MX6ULL EVK 开发板对应的设备树文件。至此我们得到两个文件:
①、 Linux 内核镜像文件: zImage。
②、 NXP 官方 I.MX6ULL EVK 开发板对应的设备树文件: imx6ull-14x14-evk.dtb。

3 Linux 内核启动测试

在上一小节我们已经得到了 NXP 官方 I.MX6ULL EVK 开发板对应的 zImage 和 imx6ull-14x14-evk.dtb 这两个文件。这两个文件能不能在正点原子的 I.MX6U-ALPHA EMMC 版开发板上启动呢?测试一下不就知道了,在测试之前确保 uboot 中的环境变量 bootargs 内容如下:

console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw

将上一小节编译出来的 zImage 和 imx6ull-14x14-evk.dtb 复制到 Ubuntu 中的 tftp 目录下,因为我们要在uboot 中使用 tftp 命令将其下载到开发板中,拷贝命令如下:

cp arch/arm/boot/zImage /home/alientek/linux/tftp/ -f
cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb /home/alientek/linux/tftp/ -f

拷贝完成以后就可以测试了,启动开发板,进入 uboot 命令行模式,然后输入如下命令将zImage 和 imx6ull-14x14-evk.dtb 下载到开发板中并启动:

tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 - 83000000

结果图所示:

此时 Linux 内核已经启动了,如果 EMMC 中的根文件系统存在,我们就可以进入到 Linux 系统里面使用命令进行操作如图 所示
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第2张图片

修改完成以后重新从网络启动,启动以后会有如图 所示错误:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第3张图片

在图 中最后会有下面这一行:

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

也就是提示内核崩溃,因为 VFS(虚拟文件系统)不能挂载根文件系统,因为根文件系统目录不存在。即使根文件系统目录存在,如果根文件系统目录里面是空的依旧会提示内核崩溃。这个就是根文件系统缺失导致的内核崩溃,但是内核是启动了的,只是根文件系统不存在而已。

2.移植到自己的arm平台

1 添加开发板默认配置文件

将 arch/arm/configs 目 录 下 的 imx_v7_mfg_defconfig 重 新 复 制 一 份 , 命 名 为imx_alientek_emmc_defconfig,命令如下:

cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig

以后 imx_alientek_emmc_defconfig 就是正点原子的 EMMC 版开发板默认配置文件了。完成以后如图所示:
在这里插入图片描述

以后就可以使用如下命令来配置正点原子 EMMC 版开发板对应的 Linux 内核了:

make imx_alientek_emmc_defconfig

2 添加开发板对应的设备树文件

添加适合正点原子EMMC 版开发板的设备树文件,进入目录 arch/arm/boot/dts 中,复制一
份 imx6ull-14x14-evk.dts,然后将其重命名为 imx6ull-alientek-emmc.dts,命令如下:

cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts

.dts 是设备树源码文件,编译 Linux 的时候会将其编译为.dtb 文件。imx6ull-alientek-emmc.dts创 建 好 以 后 我 们 还 需 要 修 改 文 件 arch/arm/boot/dts/Makefile , 找 到 “ dtb-$(CONFIG_SOC_IMX6ULL)”配置项,在此配置项中加入“imx6ull-alientek-emmc.dtb” ,如下所示:

alientek@ubuntu16:~/IMX6/nxp_linux/arch/arm/boot/dts$ vi Makefile
400 dtb-$(CONFIG_SOC_IMX6ULL) += \
401     imx6ull-14x14-ddr3-arm2.dtb \
402     imx6ull-14x14-ddr3-arm2-adc.dtb \
403     imx6ull-14x14-ddr3-arm2-cs42888.dtb \
404     imx6ull-14x14-ddr3-arm2-ecspi.dtb \
405     imx6ull-14x14-ddr3-arm2-emmc.dtb \
406     imx6ull-14x14-ddr3-arm2-epdc.dtb \
407     imx6ull-14x14-ddr3-arm2-flexcan2.dtb \
408     imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb \
409     imx6ull-14x14-ddr3-arm2-lcdif.dtb \
410     imx6ull-14x14-ddr3-arm2-ldo.dtb \
411     imx6ull-14x14-ddr3-arm2-qspi.dtb \
412     imx6ull-14x14-ddr3-arm2-qspi-all.dtb \
413     imx6ull-14x14-ddr3-arm2-tsc.dtb \
414     imx6ull-14x14-ddr3-arm2-uart2.dtb \
415     imx6ull-14x14-ddr3-arm2-usb.dtb \
416     imx6ull-14x14-ddr3-arm2-wm8958.dtb \
417     imx6ull-14x14-evk.dtb \
418     imx6ull-14x14-evk-btwifi.dtb \
419     imx6ull-14x14-evk-emmc.dtb \
420     imx6ull-14x14-evk-gpmi-weim.dtb \
421     imx6ull-14x14-evk-usb-certi.dtb \
422     imx6ull-9x9-evk.dtb \
423     imx6ull-alientek-emmc.dtb \
424     imx6ull-9x9-evk-btwifi.dtb \
425     imx6ull-9x9-evk-ldo.dtb

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第4张图片

第 423 行为“imx6ull-alientek-emmc.dtb”,这样编译 Linux 的时候就可以从 imx6ull-alientekemmc.dts 编译出 imx6ull-alientek-emmc.dtb 文件了。

3 编译测试

Linux 内核里面已经添加了正点原子 I.MX6UL-ALIPHAEMMC 版 开 发 板 了 , 接 下 接 编 译 测 试 一 下 , 我 们 可 以 创 建 一 个 编 译 脚 本 ,imx6ull_alientek_emmc.sh,脚本内容如下:
alientek@ubuntu16:~/IMX6/nxp_linux$ touch imx6ull_alientek_emmc.sh

 chmod 777 imx6ull_alientek_emmc.sh 
vi imx6ull_alientek_emmc.sh
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

第 2 行,清理工程。
第 3 行,使用默认配置文件 imx_alientek_emmc_defconfig 来配置 Linux 内核。
第 4 行,打开 Linux 的图形配置界面,如果不需要每次都打开图形配置界面可以删除此行。
第 5 行,编译 Linux。执行 shell 脚本 imx6ull_alientek_emmc.sh 编译 Linux 内核, 命令如下:

./imx6ull_alientek_emmc.sh //执行 shell 脚本编译内核

编译的时候,会出现make menuconfig界面,按两下esc按键即可,编译完成以后就会在目录 arch/arm/boot 下生成 zImage 镜像文件。在 arch/arm/boot/dts 目录下生成 imx6ull-alientek-emmc.dtb 文件。将这两个文件拷贝到 tftp 目录下,然后重启开发板,在uboot 命令模式中使用 tftp 命令下载这两个文件并启动,命令如下:

cp arch/arm/boot/zImage /home/alientek/linux/tftp/ -f
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb /home/alientek/linux/tftp/ -f
tftp 80800000 zImage
tftp 83000000 imx6ull-alientek-emmc.dtb
bootz 80800000 - 83000000

只要出现如图 所示内容就表示 Linux 内核启动成功:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第5张图片

Linux 内核启动成功,说明我们已经在 NXP 提供的 Linux 内核源码中添加了正点原子I.MX6UL-ALPHA 开发板。

3.cpu主频和网络驱动修改

1 CPU 主频修改(无需修改)跳过此节即可

正点原子 I.MX6U-ALPHA 开发板所使用的 I.MX6ULL 芯片主频都是 792MHz 的,也就是NXP 官方宣传的 800MHz 版本。后续可能会生产 528MHz 核心板供企业级批量用户,但是开发板搭配的都是 792MHz 主频的。

1、设置 I.MX6U-ALPHA 开发板工作在 792MHz

确保 EMMC 中的根文件系统可用!然后重新启动开发板,进入终端(可以输入命令),如图 所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第6张图片

进入图所示的命令行以后输入如下命令查看 cpu 信息:

cat /proc/cpuinfo

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第7张图片

processor       : 0
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 12.00
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5


Hardware        : Freescale i.MX6 Ultralite (Device Tree)
Revision        : 0000
Serial          : 0000000000000000

在图中有 BogoMIPS 这一条,此时 BogoMIPS 为 12.00, BogoMIPS 是 Linux 系统中衡量处理器运行速度的一个“尺子”,处理器性能越强,主频越高, BogoMIPS 值就越大。BogoMIPS 只是粗略的计算 CPU 性能,并不十分准确。但是我们可以通过 BogoMIPS 值来大致的判断当前处理器的性能。在图中并没有看到当前 CPU 的工作频率,那我们就转变另一种方法查看当前 CPU 的工作频率。进入到目录/sys/bus/cpu/devices/cpu0/cpufreq 中,此目录下会有很多文件,如图所示:

cd /sys/bus/cpu/devices/cpu0/cpufreq
ls

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第8张图片

此目录中记录了 CPU 频率等信息,这些文件的含义如下:
cpuinfo_cur_freq:当前 cpu 工作频率,从CPU 寄存器读取到的工作频率。
cpuinfo_max_freq:处理器所能运行的最高工作频率(单位: KHz)。
cpuinfo_min_freq :处理器所能运行的最低工作频率(单位: KHz)。
cpuinfo_transition_latency:处理器切换频率所需要的时间(单位:ns)。
scaling_available_frequencies:处理器支持的主频率列表(单位: KHz)。
scaling_available_governors:当前内核中支持的所有 governor(调频)类型。
scaling_cur_freq:保存着 cpufreq 模块缓存的当前 CPU 频率,不会对 CPU 硬件寄存器进行检查。
scaling_driver:该文件保存当前 CPU 所使用的调频驱动。
scaling_governor:governor(调频)策略,Linux 内核一共有 5 中调频策略,
①、Performance,最高性能,直接用最高频率,不考虑耗电。
②、Interactive,一开始直接用最高频率,然后根据CPU 负载慢慢降低。
③、Powersave,省电模式,通常以最低频率运行,系统性能会受影响,一般不会用这个!
④、Userspace,可以在用户空间手动调节频率。
⑤、Ondemand,定时检查负载,然后根据负载来调节频率。负载低的时候降低 CPU 频率,这样省电,负载高的时候提高CPU 频率,增加性能。
scaling_max_freq:governor(调频)可以调节的最高频率。
cpuinfo_min_freq:governor(调频)可以调节的最低频率。
stats 目录下给出了 CPU 各种运行频率的统计情况,比如 CPU 在各频率下的运行时间以及变频次数。
使用如下命令查看当前CPU 频率

cat cpuinfo_cur_freq

从图可以看出,当前 CPU 频率为 792MHz,其他的值如下:

cpuinfo_cur_freq = 792000
cpuinfo_max_freq = 792000
cpuinfo_min_freq = 198000
scaling_cur_freq = 792000
scaling_max_freq = 792000
cat scaling_min_freq = 198000
scaling_available_frequencies = 198000 396000 528000 792000
cat scaling_governor = conservative ondemand userspace powersave performance

可以看出,当前 CPU 支持 198MHz、 396MHz、 528Mhz 和 792MHz 四种频率切换,其中调频策略为 ondemand,也就是定期检查负载,然后根据负载情况调节 CPU 频率。因为当前我们开发板并没有做什么工作,因此 CPU 频率降低为 198MHz 以省电。如果开发板做一些高负载的工作,比如播放视频等操作那么 CPU 频率就会提升上去。查看 stats 目录下的 time_in_state 文件可以看到 CPU 在各频率下的工作时间,命令如下:

cat /sys/bus/cpu/devices/cpu0/cpufreq/stats/time_in_state

结果如图
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第9张图片

从图 中可以看出, CPU 在 198MHz、 396MHz、 528MHz 都没有工作过,其中 ,始终工作在792MHz!假如我们想让 CPU 一直工作在 792MHz 那该怎么办?很简单,配置 Linux 内核,将调频策略选择为 performance。或者修改 imx_alientek_emmc_defconfig 文件,此文件中有下面几行:

cd arch/arm/configs/
vi imx_alientek_emmc_defconfig 

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第10张图片

42 CONFIG_CPU_FREQ=y
43 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
44 CONFIG_CPU_FREQ_GOV_USERSPACE=y
45 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
46 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
47 CONFIG_ARM_IMX6Q_CPUFREQ=y
48 CONFIG_CPU_IDLE=y

第 41 行,配置 ondemand 为默认调频策略。
第 42 行,使能 powersave 策略。
第 43 行,使能 userspace 策略。
第 44 行,使能 interactive 策略。
performance:CPU将始终以其支持的最高运行频率运行。
powersave:CPU将始终以其支持的最低运行频率运行。
userspace:允许用户空间应用程序通过相应的接口调节CPU运行频率。
ondemand:根据系统负载自动调整CPU运行频率。
conservative:类似于ondemand,但调整CPU运行频率时更加保守。
将示例代码 中的第 41 行屏蔽掉,然后在 44 行后面添加:

CONFIG_CPU_FREQ_GOV_ONDEMAND=y

结果下所示:

41 #CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
42 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
43 CONFIG_CPU_FREQ_GOV_USERSPACE=y
44 CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
45 CONFIG_CPU_FREQ_GOV_ONDEMAND=y

修改完成以后重新编译 Linux 内核,编译之前先清理一下工程!因为我们重新修改过默认配 置 文 件 了 , 编 译完成 以 后 使 用 新的 zImage 镜 像 文 件 重新 启动 Linux 。 再 次 查 看/sys/devices/system/cpu/cpu0/cpufreq/ cpuinfo_cur_freq 文件的值,如图 所示:

在这里插入图片描述

从图可以看出,当前 CPU 频率为 792MHz 了。查看 scaling_governor 文件看一下当前的调频策略,如图 所示
在这里插入图片描述

从图 可以看出当前的 CPU 调频策略为 preformance,也就是高性能模式,一直以最高主频运行。
我们再来看一下如何通过图形化界面配置 Linux 内核的 CPU 调频策略,输入“ makemenuconfig”打开 Linux 内核的图形化配置界面,如图 所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第11张图片

进入如下路径:

CPU Power Management
    -> CPU Frequency scaling
        -> Default CPUFreq governor

打开默认调频策略选择界面,选择“performance”,如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第12张图片

在图 中选择“‘performance’ governor”即可,选择以后退出图形化配置界面,然后编译 Linux内核,一定不要清理工程!否则的话我们刚刚的设置就会被清理掉。编译完成以后使用新的zImage 重启 Linux,查看当前 CPU 的工作频率和调频策略。我们学习的时候为了高性能,大家可以使用 performance 模式。但是在以后的实际产品开发中,从省电的角度考虑,建议大家使用 ondemand 模式,一来可以省电,二来可以减少发热。

2、超频至 700MHz

I.MX6ULL 有多种型号,按照工作频率可以分为 528MHz、 700Mhz(实际 696MHz),800MHz(实际 792MHz)和 900MHz(实际频率未知,应该在 900MHz 左右)。 有些朋友可能用的其他品牌的开发板,其所使用的 I.MX6ULL 主频可能是 528MHz 的,虽然芯片标称是 528MHz 主频,但是其是可以超频的 700MHz 的(这里的 700MHz 实际上只有 696MHz,但是 NXP 官方宣传其为 700MHz,所以我们就统一称为 700MHz 吧)。

对于所用的芯片为 528MHz 主频但是想体验一下高性能的朋友体验一下超频,笔者测试过528MHz 超频到 700MHz,还没有出现过超频不稳定的现象发生,但是!毕竟是超频了的,肯定没有工作在 528MHz 稳定。
超频设置其实很简单,修改一下设备树文件 arch/arm/boot/dts/imx6ull.dtsi 即可,打开imx6ull.dtsi,找到下面代码:

  50     cpus {
  51         #address-cells = <1>;
  52         #size-cells = <0>;
  53 
  54         cpu0: cpu@0 {
  55             compatible = "arm,cortex-a7";
  56             device_type = "cpu";
  57             reg = <0>;
  58             clock-latency = <61036>; /* two CLK32 periods */
  59             operating-points = <
  60                 /* kHz  uV */
  61                 996000  1275000
  62                 792000  1225000
  63                 528000  1175000
  64                 396000  1025000
  65                 198000  950000
  66             >;
  67             fsl,soc-operating-points = <
  68                 /* KHz  uV */
  69                 996000  1175000
  70                 792000  1175000
  71                 528000  1175000
  72                 396000  1175000
  73                 198000  1175000
  74             >;
  75             fsl,low-power-run;
  76             clocks = <&clks IMX6UL_CLK_ARM>,
  77                  <&clks IMX6UL_CLK_PLL2_BUS>,
  78                  <&clks IMX6UL_CLK_PLL2_PFD2>,
  79                  <&clks IMX6UL_CA7_SECONDARY_SEL>,
  80                  <&clks IMX6UL_CLK_STEP>,
  81                  <&clks IMX6UL_CLK_PLL1_SW>,
  82                  <&clks IMX6UL_CLK_PLL1_SYS>,
  83                  <&clks IMX6UL_PLL1_BYPASS>,
  84                  <&clks IMX6UL_CLK_PLL1>,
  85                  <&clks IMX6UL_PLL1_BYPASS_SRC>,
  86                  <&clks IMX6UL_CLK_OSC>;
  87             clock-names = "arm", "pll2_bus",  "pll2_pfd2_396m", "secondary_sel", "step",
  88                       "pll1_sw", "pll1_sys", "pll1_bypass", "pll1", "pll1_bypass_src", "osc";
  89         };
  90     };

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第13张图片

示例代码就是设置 CPU 频率的,第 61~65 行和第 69~73 行就是 I.MX6ULL 所支持的频率,单位为 KHz,可以看出 I.MX6ULL(视具体型号而定)支持 996MHz、 792MHz、 528MHz、396MHz 和 198MHz。在上一小节中,我们知道 Linux 内核默认支持 198MHz、 396MHz、 528MHz和 792MHz, 如果是 MCIMX6Y2CVM05AB 这颗芯片的话,默认最高只能运行在 528MHz, 我们在示例代码 中加入针对 696MHz 的支持,修改以后代码如下:

54 cpu0: cpu@0 {
55     compatible = "arm,cortex-a7";
56     device_type = "cpu";
57     reg = <0>;
58     clock-latency = <61036>; /* two CLK32 periods */
59     operating-points = <
60        /* kHz  uV */
61        996000  1275000
62        792000  1225000
63        696000  1225000
64        528000  1175000
65        396000  1025000
66        198000  950000
67     >;
68     fsl,soc-operating-points = <
69         /* KHz  uV */
70         996000  1175000
71         792000  1175000
72         696000  1175000
73         528000  1175000
74         396000  1175000
75         198000  1175000
76  >;

第 63 行,加入了“696000 1225000”,这个就是 696MHz 的支持。
第 72 行,加入了“696000 1175000”,也是对 696MHz 的支持。
修改好以后保存,并且编译设备树,在 Linux 内核源码根目录下输入如下命令编译设备树:

make dtbs

命令“make dtbs”只编译设备树文件,也就是将.dts 编译为.dtb,编译完成以后使用新的设备 树 文 件 imx6ull-alientek_emmc.dtb 启 动 Linux 。 重 启 以 后 查 看 文 件/sys/devices/system/cpu/cpu0/cpufreq/ scaling_available_frequencies 的内容,如图 所示:
在这里插入图片描述

从图 37.4.1.11 可以看出,此时支持了 696MHz。如果设置调频策略为 performance,那么处理器就会一直工作在 696MHz。可以对比一下工作在 528MHz 和 696MHz 下的 BogoMIPS 的值,528MHz 主频下的 BogoMIPS 值如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第14张图片

696MHz 主频下的 BogoMIPS 值如图 所示:

从两张图中可以看到, 528MHz 和 696MHz 下的 BogoMIPS 值分别为8.00 和 10.54,相当于性能提升了(10.54/8)-1=31.75%。

2 使能 8 线 EMMC 驱动

正点原子 EMMC 版本核心板上的 EMMC 采用的 8 位数据线,原理图如图 所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第15张图片

Linux 内核驱动里面 EMMC 默认是 4 线模式的, 4 线模式肯定没有 8 线模式的速度快,所以本节我们将 EMMC 的驱动修改为 8 线模式。修改方法很简单,直接修改设备树即可,打开文件 imx6ull-alientek-emmc.dts,找到如下所示内容:

734 &usdhc2 {
735     pinctrl-names = "default";
736     pinctrl-0 = <&pinctrl_usdhc2>;
737     non-removable;
738     status = "okay";
739 };

只需要将其改为如下代码即可:

734 &usdhc2 {
735     pinctrl-names = "default", "state_100mhz", "state_200mhz";
736     pinctrl-0 = <&pinctrl_usdhc2_8bit>;
737     pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
738     pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
739     bus-width = <8>;
740     non-removable;
741     status = "okay";
742 };

修改完成以后保存一下 imx6ull-alientek-emmc.dts,然后使用命令“make dtbs”重新编译一下设备树,编译完成以后使用新的设备树重启 Linux 系统即可。

3 修改网络驱动

Linux 驱动开发的时候要用到网络调试驱动,所以必须要把网络驱动调试好。在讲解 uboot 移植的时候就已经说过了,正点原子开发板的网络和 NXP 官方的网络硬件上不同,网络 PHY 芯片由 KSZ8081 换为了 LAN8720A,两个网络 PHY 芯片的复位 IO 也不同。所以 Linux 内核自带的网络驱动是驱动不起来 I.MX6U-ALPHA 开发板上的网络的,需要做修改。

1、修改 LAN8720 的复位以及网络时钟引脚驱动

ENET1 复位引脚 ENET1_RST 连接在 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。 ENET2的复位引脚 ENET2_RST 连接在 I.MX6ULL 的 SNVS_TAMPER8 上。打开设备树文件 imx6ullalientek-emmc.dts,找到如下代码:

584         pinctrl_spi4: spi4grp {
585                         fsl,pins = <
586                                 MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
587                                 MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
588                                 MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x70a1
589                                 MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x80000000
590                         >;
591                 };

第 588 和 589 行就是初始化 SNVS_TAMPER7 和 SNVS_TAMPER8 这两个引脚的,不过看样子好像是作为了 SPI4 的 IO,这不是我们想要的,所以将 588 和 589 这两行删除掉!
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第16张图片

删除掉以后继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码:

125     spi4 {
126         compatible = "spi-gpio";
127         pinctrl-names = "default";
128         pinctrl-0 = <&pinctrl_spi4>;
129         pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
130         status = "okay";
131         gpio-sck = <&gpio5 11 0>;
132         gpio-mosi = <&gpio5 10 0>;
133         cs-gpios = <&gpio5 7 0>;
134         num-chipselects = <1>;
135         #address-cells = <1>;
136         #size-cells = <0>;
137
138         gpio_spi: gpio_spi@0 {
139             compatible = "fairchild,74hc595";
140             gpio-controller;
141             #gpio-cells = <2>;
142             reg = <0>;
143             registers-number = <1>;
144             registers-default = /bits/ 8 <0x57>;
145             spi-max-frequency = <100000>;
146         };
147     };

第 129 行,设置 GPIO5_IO08 为 SPI4 的一个功能引脚(我也不清楚具体作为什么功能用),而 GPIO5_IO08 就是 SNVS_TAMPER8 的 GPIO 功能引脚。
第 133 行,设置 GPIO5_IO07 作为 SPI4 的片选引脚,而 GPIO5_IO07 就是 SNVS_TAMPER7的 GPIO 功能引脚。
现在我们需要 GPIO5_IO07 和 GPIO5_IO08 分别作为 ENET1 和 ENET2 的复位引脚,而不是 SPI4 的什么功能引脚,因此将示例代码 中的第 129 行和第 133 行处的代码删除掉!!否则会干扰到网络复位引脚!
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第17张图片

125     spi4 {
126         compatible = "spi-gpio";
127         pinctrl-names = "default";
128         pinctrl-0 = <&pinctrl_spi4>;
129         /* pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; */
130         status = "okay";
131         gpio-sck = <&gpio5 11 0>;
132         gpio-mosi = <&gpio5 10 0>;
133         /* cs-gpios = <&gpio5 7 0>;*/ 
134         num-chipselects = <1>;
135         #address-cells = <1>;
136         #size-cells = <0>;
137 
138         gpio_spi: gpio_spi@0 {
139             compatible = "fairchild,74hc595";
140             gpio-controller;
141             #gpio-cells = <2>;
142             reg = <0>;
143             registers-number = <1>;
144             registers-default = /bits/ 8 <0x57>;
145             spi-max-frequency = <100000>;
146         };  
147     };

在 imx6ull-alientek-emmc.dts 里面找到名为“iomuxc_snvs”的节点(就是直接搜索),然后在此节点下添加网络复位引脚信息,添加完成以后的“iomuxc_snvs”的节点内容如下:

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第18张图片

修改后

559 &iomuxc_snvs {
560     pinctrl-names = "default_snvs";
561         pinctrl-0 = <&pinctrl_hog_2>;
562         imx6ul-evk {
563         pinctrl_hog_2: hoggrp-2 {
564                         fsl,pins = <
565                                 MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x80000000
566                         >;
567                 };
568 
569         pinctrl_dvfs: dvfsgrp {
570                         fsl,pins = <
571                                 MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x79
572                         >;
573                 };
574 
575         pinctrl_lcdif_reset: lcdifresetgrp {
576                         fsl,pins = <
577                                 /* used for lcd reset */
578                                 MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09  0x79
579                         >;
580                 };
581 
582         pinctrl_spi4: spi4grp {
583                         fsl,pins = <
584                                 MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
585                                 MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
586                         >;
587                 };
588 
589                 pinctrl_sai2_hp_det_b: sai2_hp_det_grp {
590                         fsl,pins = <
591                                 MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04   0x17059
592                         >;
593                 };
594         /*enet1 reset paranoid paranoid*/
595         pinctrl_enet1_reset: enet1resetgrp {
596             fsl,pins = <
597                 /* used for enet1 reset */
598                     MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
599                 >;
600         };
601 
602         /*enet2 reset paranoid paranoid*/
603         pinctrl_enet2_reset: enet2resetgrp {
604                 fsl,pins = <
605                 /* used for enet2 reset */
606                     MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
607                 >;
608             };
609         };
610 };



};

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第19张图片

第 1 行,imx6ull-alientek-emmc.dts 文件中 iomuxc_snvs 节点。
第 36~42 行,ENET1 网络复位引脚配置信息。
第 44~50 行,ENET2 网络复位引脚配置信息。
最后还需要修改一下 ENET1 和 ENET2 的网络时钟引脚配置,继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码:

307         pinctrl_enet1: enet1grp {
308             fsl,pins = <
309                 MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN  0x1b0b0
310                 MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER  0x1b0b0
311                 MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
312                 MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
313                 MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN  0x1b0b0
314                 MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
315                 MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
316                 MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031
317             >;
318         };
319 
320         pinctrl_enet2: enet2grp {
321             fsl,pins = <
322                 MX6UL_PAD_GPIO1_IO07__ENET2_MDC     0x1b0b0
323                 MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0
324                 MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN  0x1b0b0
325                 MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER  0x1b0b0
326                 MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
327                 MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
328                 MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN  0x1b0b0
329                 MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
330                 MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
331                 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031
332             >;

333 };

第 318 和 333 行, 分别为 ENET1 和 ENET2 的网络时钟引脚配置信息,将这两个引脚的电气属性值改为 0x4001b009,原来默认值为 0x4001b031。
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第20张图片

307         pinctrl_enet1: enet1grp {
308             fsl,pins = <
309                 MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN  0x1b0b0
310                 MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER  0x1b0b0
311                 MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
312                 MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
313                 MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN  0x1b0b0
314                 MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
315                 MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
316                 MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b009
317             >;
318         };
319 
320         pinctrl_enet2: enet2grp {
321             fsl,pins = <
322                 MX6UL_PAD_GPIO1_IO07__ENET2_MDC     0x1b0b0
323                 MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0
324                 MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN  0x1b0b0
325                 MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER  0x1b0b0
326                 MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
327                 MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
328                 MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN  0x1b0b0
329                 MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
330                 MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
331                 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b009
332             >;
333         };

修改完成以后记得保存一下 imx6ull-alientek-emmc.dts,网络复位以及时钟引脚驱动就修改好了。

2、修改 fec1 和 fec2 节点的 pinctrl-0 属性

在 imx6ull-alientek-emmc.dts 文件中找到名为“fec1”和“fec2”的这两个节点,修改其中的“pinctrl-0”属性值,修改以后如下所示:
修改前

169 &fec1 {
170     pinctrl-names = "default";
171     pinctrl-0 = <&pinctrl_enet1>;
172     phy-mode = "rmii";
173     phy-handle = <&ethphy0>;
174     status = "okay";
175 };
176 
177 &fec2 {
178     pinctrl-names = "default";
179     pinctrl-0 = <&pinctrl_enet2>;
180     phy-mode = "rmii";
181     phy-handle = <&ethphy1>;
182     status = "okay";
183 
184     mdio {
185         #address-cells = <1>;
186         #size-cells = <0>;
187 
188         ethphy0: ethernet-phy@2 {
189             compatible = "ethernet-phy-ieee802.3-c22";
190             reg = <2>;
191         };
192 
193         ethphy1: ethernet-phy@1 {
194             compatible = "ethernet-phy-ieee802.3-c22";
195             reg = <1>;
196         };
197     };
198 };

修改后

169 &fec1 {
170     pinctrl-names = "default";
171     pinctrl-0 = <&pinctrl_enet1
172                  &pinctrl_enet1_reset>;
173     phy-mode = "rmii";
174     phy-handle = <&ethphy0>;
175     status = "okay";
176 };
177 
178 &fec2 {
179     pinctrl-names = "default";
180     pinctrl-0 = <&pinctrl_enet2
181                  &pinctrl_enet1_reset>;
182     phy-mode = "rmii";
183     phy-handle = <&ethphy1>;
184     status = "okay";
185 
186     mdio {
187         #address-cells = <1>;
188         #size-cells = <0>;
189 
190         ethphy0: ethernet-phy@2 {
191             compatible = "ethernet-phy-ieee802.3-c22";
192             reg = <2>;
193         };
194 
195         ethphy1: ethernet-phy@1 {
196             compatible = "ethernet-phy-ieee802.3-c22";
197             reg = <1>;
198         };
199     };
200 };

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第21张图片

第 3行,修改后的 fec1 节点“pinctrl-0”属性值。第 12 行,修改后的 fec2 节点“pinctrl-0”属性值。

3、修改 LAN8720A 的 PHY 地址

在 uboot 移植章节中,我们说过 ENET1 的 LAN8720A 地址为 0x0, ENET2 的 LAN8720A地址为 0x1。在 imx6ull-alientek-emmc.dts 中找到如下代码:

169 &fec1 {
170     pinctrl-names = "default";
171     pinctrl-0 = <&pinctrl_enet1
172                  &pinctrl_enet1_reset>;
173     phy-mode = "rmii";
174     phy-handle = <&ethphy0>;
175     status = "okay";
176 };
177 
178 &fec2 {
179     pinctrl-names = "default";
180     pinctrl-0 = <&pinctrl_enet2
181                  &pinctrl_enet1_reset>;
182     phy-mode = "rmii";
183     phy-handle = <&ethphy1>;
184     status = "okay";
185 
186     mdio {
187         #address-cells = <1>;
188         #size-cells = <0>;
189 
190         ethphy0: ethernet-phy@2 {
191             compatible = "ethernet-phy-ieee802.3-c22";
192             reg = <2>;
193         };
194 
195         ethphy1: ethernet-phy@1 {
196             compatible = "ethernet-phy-ieee802.3-c22";
197             reg = <1>;
198         };
199     };
200 };

第 169~177 行, ENET1 对应的设备树节点。第 178~200 行, ENET2 对应的设备树节点。但是第 186~198 行的 mdio 节点描述了 ENET1和 ENET2 的 PHY 地址信息。将示例代码 改为如下内容:

171 &fec1 {
172     pinctrl-names = "default";
173     pinctrl-0 = <&pinctrl_enet1
174                  &pinctrl_enet1_reset>;
175     phy-mode = "rmii";
176     phy-handle = <&ethphy0>;
177     phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
178     phy-reset-duration = <200>;
179     status = "okay";
180 };
181 
182 &fec2 {
183     pinctrl-names = "default";
184     pinctrl-0 = <&pinctrl_enet2
185                  &pinctrl_enet1_reset>;
186     phy-mode = "rmii";
187     phy-handle = <&ethphy1>;
188     status = "okay";
189 
190     mdio {
191         #address-cells = <1>;
192         #size-cells = <0>;
193 
194         ethphy0: ethernet-phy@0 {
195             compatible = "ethernet-phy-ieee802.3-c22";
196             reg = <0>;
197         };
198 
199         ethphy1: ethernet-phy@1 {
200             compatible = "ethernet-phy-ieee802.3-c22";
201             reg = <1>;
202         };
203     };
204 };

第 177 和 178 行,添加了 ENET1 网络复位引脚所使用的 IO 为 GPIO5_IO07,低电平有效。复位低电平信号持续时间为 200ms。第 188 和 189 行, ENET2 网络复位引脚所使用的 IO 为 GPIO5_IO08,同样低电平有效,持续时间同样为 200ms。
第 198 和 204 行,“smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A。第 196 行,注意“ethernet-phy@”后面的数字是 PHY 的地址, ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)。
第 199 行, reg 的值也表示 PHY 地址, ENET1 的 PHY 地址为 0,所以 reg=0。第 202 行, ENET2 的 PHY 地址为 1,因此“@”后面为 1。
第 205 行,因为 ENET2 的 PHY 地址为 1,所以 reg=1。
至此, LAN8720A 的 PHY 地址就改好了,保存一下 imx6ull-alientek-emmc.dts 文件。然后使用“make dtbs”命令重新编译一下设备树。

4、修改 fec_main.c 文件

要 在 I.MX6ULL 上 使 用 LAN8720A , 需 要 修 改 一 下 Linux 内 核 源 码 , 打 开drivers/net/ethernet/freescale/fec_main.c,找到函数 fec_probe,在 fec_probe 中加入如下代码:
修改前

3438 static int
3439 fec_probe(struct platform_device *pdev)
3440 {
3441     struct fec_enet_private *fep;
3442     struct fec_platform_data *pdata;
3443     struct net_device *ndev;
3444     int i, irq, ret = 0;
3445     struct resource *r;
3446     const struct of_device_id *of_id;
3447     static int dev_id;
3448     struct device_node *np = pdev->dev.of_node, *phy_node;
3449     int num_tx_qs;
3450     int num_rx_qs;
3451 
3452     fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
3453 
3454     /* Init network device */
3455     ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
3456                   num_tx_qs, num_rx_qs);
3457     if (!ndev)
3458         return -ENOMEM;
3459 
3460     SET_NETDEV_DEV(ndev, &pdev->dev);
3461 
3462     /* setup board info structure */
3463     fep = netdev_priv(ndev);
3464 
3465     of_id = of_match_device(fec_dt_ids, &pdev->dev);
3466     if (of_id)
3467         pdev->id_entry = of_id->data;
3468     fep->quirks = pdev->id_entry->driver_data;
3469 
3470     fep->netdev = ndev;
3471     fep->num_rx_queues = num_rx_qs;
。。。。。

修改后

 static int
3439 fec_probe(struct platform_device *pdev)
3440 {
3441     struct fec_enet_private *fep;
3442     struct fec_platform_data *pdata;
3443     struct net_device *ndev;
3444     int i, irq, ret = 0;
3445     struct resource *r;
3446     const struct of_device_id *of_id;
3447     static int dev_id;
3448     struct device_node *np = pdev->dev.of_node, *phy_node;
3449     int num_tx_qs;
3450     int num_rx_qs;
3451 
3452     /* 设置 MX6UL_PAD_ENET1_TX_CLK 和 MX6UL_PAD_ENET2_TX_CLK
3453      * 这两个 IO 的复用寄存器的 SION 位为 1。
3454      */
3455     void __iomem *IMX6U_ENET1_TX_CLK;
3456     void __iomem *IMX6U_ENET2_TX_CLK;
3457 
3458     IMX6U_ENET1_TX_CLK = ioremap(0X020E00DC, 4);
3459     writel(0X14, IMX6U_ENET1_TX_CLK);
3460 
3461     IMX6U_ENET2_TX_CLK = ioremap(0X020E00FC, 4);
3462     writel(0X14, IMX6U_ENET2_TX_CLK);
3463     fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
3464 
3465     /* Init network device */
3466     ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
3467                   num_tx_qs, num_rx_qs);
3468     if (!ndev)
3469         return -ENOMEM;
3470     
3471     SET_NETDEV_DEV(ndev, &pdev->dev);
3472     
3473     /* setup board info structure */

第 3455~3462 就是新加入的代码,如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1。

5、配置 Linux 内核,使能 LAN8720 驱动

输入命令“make menuconfig”,打开图形化配置界面,选择使能 LAN8720A 的驱动,路径如下:

-> Device Drivers
    -> Network device support
        -> PHY Device support and infrastructure
            -> Drivers for SMSC PHYs

如图 所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第22张图片

选择将“Drivers for SMSC PHYs”编译到 Linux 内核中,因此“<>”里面变为了“*”。 LAN8720A 是 SMSC 公司出品的,因此勾选这个以后就会编译 LAN8720 驱动,配置好以后退出配置界面。

6、修改 smsc.c 文件

在修改 smsc.c 文件之前先说点题外话,那就是我是怎么确定要修改 smsc.c 这个文件的。在写本书之前我并没有修改过 smsc.c 这个文件,都是使能 LAN8720A 驱动以后就直接使用。但是我在测试 NFS 挂载文件系统的时候发现文件系统挂载成功率很低!老是提示 NFS 服务器找不到,三四次就有一次挂载失败!很折磨人。 NFS 挂载就是通过网络来挂载文件系统,这样做的好处就是方便我们后续调试 Linux 驱动。既然老是挂载失败那么可以肯定的是网络驱动有问题,网络驱动分两部分:内部 MAC+外部 PHY,内部 MAC 驱动是由 NXP 提供的,一般不会出问题,否则的话用户早就给 NXP 反馈了。而且我用 NXP 官方的开发板测试网络是一直正常的,但是 NXP 官方的开发板所使用的 PHY 芯片为 KSZ8081。所以只有可能是外部 PHY,也就是LAN8720A 的驱动可能出问题了。鉴于 LAN8720A 有“前车之鉴”,那就是在 uboot 中需要对LAN8720A 进行一次软复位,要设置 LAN8720A 的 BMCR(寄存器地址为 0)寄存器 bit15 为 1。所以我猜测,在 Linux 中也需要对 LAN8720A 进行一次软复位。
首先需要找到 LAN8720A 的驱动文件, LAN8720A 的驱动文件是 drivers/net/phy/smsc.c,在此文件中有个叫做 smsc_phy_reset 的函数,看名字都知道这是 SMSC PHY 的复位函数,因此, LAN8720A 肯定也会使用到这个复位函数, 修改此函数的内容,修改以后的 smsc_phy_reset函数内容如下所示:
修改前

 60 static int smsc_phy_reset(struct phy_device *phydev)
 61 {
 62     int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
 63     if (rc < 0)
 64         return rc;
 65 
 66     /* If the SMSC PHY is in power down mode, then set it
 67      * in all capable mode before using it.
 68      */
 69     if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) {
 70         int timeout = 50000;
 71 
 72         /* set "all capable" mode and reset the phy */
 73         rc |= MII_LAN83C185_MODE_ALL;
 74         phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
 75         phy_write(phydev, MII_BMCR, BMCR_RESET);
 76 
 77         /* wait end of reset (max 500 ms) */
 78         do {
 79             udelay(10);
 80             if (timeout-- == 0)
 81                 return -1;
 82             rc = phy_read(phydev, MII_BMCR);
 83         } while (rc & BMCR_RESET);
 84     }
 85     return 0;
 86 }

修改后

 static int smsc_phy_reset(struct phy_device *phydev)
{
      int err, phy_reset;
      int msec = 1;
      struct device_node *np;
      int timeout = 50000;
      if(phydev->addr == 0) /* FEC1  */ {
            np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
            if(np == NULL) {
                 return -EINVAL;
         }
     }

      if(phydev->addr == 1) /* FEC2  */ {
            np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000");
            if(np == NULL) {
                return -EINVAL;
            }   
    }   

     err = of_property_read_u32(np, "phy-reset-duration", &msec);
     /* A sane reset duration should not be longer than 1s */
     if (!err && msec > 1000)
         msec = 1;
     phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0); 
     if (!gpio_is_valid(phy_reset))
         return;

     gpio_direction_output(phy_reset, 0); 
     gpio_set_value(phy_reset, 0); 
     msleep(msec);
     gpio_set_value(phy_reset, 1); 

    int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
    if (rc < 0)
        return rc; 

    /* If the SMSC PHY is in power down mode, then set it
     * in all capable mode before using it.
     */
102     if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) {
103 
104         /* set "all capable" mode and reset the phy */
105         rc |= MII_LAN83C185_MODE_ALL;
106         phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
107         }
108         phy_write(phydev, MII_BMCR, BMCR_RESET);
109 
110         /* wait end of reset (max 500 ms) */
111     do {
112         udelay(10);
113         if (timeout-- == 0)
114             return -1; 
115         rc = phy_read(phydev, MII_BMCR);
116     } while (rc & BMCR_RESET);
117     
118     return 0;
119 }

第 7~12 行,获取 FEC1 网卡对应的设备节点。
第 14~19 行,获取 FEC2 网卡对应的设备节点。
第 21 行,从设备树中获取“phy-reset-duration”属性信息,也就是复位时间。
第 25 行,从设备树中获取“phy-reset-gpios”属性信息,也就是复位 IO。
第 29~32 行,设置 PHY 的复位 IO,复位 LAN8720A。
第 41~48 行,以前的 smsc_phy_reset 函数会判断 LAN8720 是否处于 Powerdown 模式,只有处于 Powerdown 模式的时候才会软复位 LAN8720。这里我们将软复位代码移出来,这样每次调用 smsc_phy_reset 函数 LAN8720A 都会被软复位。最后我们还需要在 drivers/net/phy/smsc.c 文件中添加两个头文件,因为修改后的smsc_phy_reset 函数用到了 gpio_direction_output 和 gpio_set_value 这两个函数,需要添加的头文件如下所示:

#include <linux/of_gpio.h>
#include <linux/io.h>

然后编译源码,启动开发板,你会发现压根进不了系统!!!!!(其他修改能解决)

4 保存修改后的图形化配置文件

在修改网络驱动的时候我们通过图形界面使能了 LAN8720A 的驱动,使能以后会在.config中存在如下代码:

CONFIG_SMSC_PHY=y

打开 drivers/net/phy/Makefile,有如下代码:

obj-$(CONFIG_SMSC_PHY) += smsc.o

当 CONFIG_SMSC_PHY=y 的时候就会编译 smsc.c 这个文件, smsc.c 就是 LAN8720A 的驱动文件。但是当我们执行“make clean”清理工程以后.config 文件就会被删除掉,因此我们所有的配置内容都会丢失,结果就是前功尽弃,一“删”回到解放前!所以我们在配置完图形界面以后经过测试没有问题,就必须要保存一下配置文件。保存配置的方法有两个。

1、直接另存为.config 文件

既然图形化界面配置后的配置项保存在.config 中,那么就简单粗暴,直接将.config 文件另存为 imx_alientek_emmc_defconfig , 然后其复制到 arch/arm/configs 目录下, 替换以前的imx_alientek_emmc_defconfig。这样以后执行“make imx_alientek_emmc_defconfig”重新配置Linux 内核的时候就会使用新的配置文件,默认就会使能LAN8720A 的驱动。

2、通过图形界面保存配置文件

相比于第 1 种直接另存为.config 文件,第 2 种方法就很“文雅”了,在图形界面中保存配
置文件,在图形界面中会有“< Save >”选项,如图所示
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第23张图片

通过键盘的“→”键,移动到“< Save >”选项,然后按下回车键,打开文件名输入对话框

Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第24张图片

在图中输入要保存的文件名,可以带路径,一般是相对路径(相对于 Linux 内核源码 根目 录 )。 比如 我们要 将新 的配 置文 件保存 到目 录 arch/arm/configs 下 , 文件 名为imx_alientek_emmc_defconfig,也就是用新的配置文件替换掉老的默认配置文件。那么我们在图中输入“arch/arm/configs/imx_alientek_emmc_defconfig”即可,如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第25张图片

设置好文件名以后选择下方的“ < Ok >”按钮,保存文件并退出。退出以后再打开imx_alientek_emmc_defconfig 文件,就会在此文件中找到“CONFIG_SMSC_PHY=y”这一行,如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第26张图片

同样的,使用“make imx_alientek_emmc_defconfig”重新配置 Linux 内核的时候,LAN8720A的驱动就会使能,并被编译进Linux 镜像文件 zImage 中。

然后重新编译一下 Linux 内核

关于Linux 内核的移植就讲解到这里,简单总结一下移植步骤:
①、在 Linux 内核中查找可以参考的板子,一般都是半导体厂商自己做的开发板。
②、编译出参考板子对应的 zImage 和.dtb 文件。
③、使用参考板子的 zImage 文件和.dtb 文件在我们所使用的板子上启动 Linux 内核,看能
否启动。
④、如果能启动的话就万事大吉,如果不能启动那就悲剧了,需要调试 Linux 内核。不过一般都会参考半导体官方的开发板设计自己的硬件,所以大部分情况下都会启动起来。启动Linux 内核用到的外设不多,一般就 DRAM(Uboot 都初始化好的)和串口。作为终端使用的串口一般都会参考半导体厂商的 Demo 板。
⑤、修改相应的驱动,像NAND Flash、EMMC、SD 卡等驱动官方的 Linux 内核都是已经提供好了,基本不会出问题。重点是网络驱动,因为 Linux 驱动开发一般都要通过网络调试代码,所以一定要确保网络驱动工作正常。如果是处理器内部 MAC+外部 PHY 这种网络方案的话,一般网络驱动都很好处理,因为在 Linux 内核中是有外部 PHY 通用驱动的。只要设置好复位引脚、PHY 地址信息基本上都可以驱动起来。
⑥、Linux 内核启动以后需要根文件系统,如果没有根文件系统的话肯定会崩溃,所以确定 Linux内核移植成功以后就要开始根文件系统的构建。

其他修改(重点,参考原子教程移植后依旧有错误,需要按下列内容修改设备树):

上述时正点原子教程提供的移植,但在移植过后,出现了好些问题,参考教程移植后,根本无法进入系统,在不断探索后终于知道设备树内容还要大改,下面时移植玩上面内容后的设备树
代码对比软件

原来

/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/dts-v1/;

#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"

/ {
    model = "Freescale i.MX6 ULL 14x14 EVK Board";
    compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";

    chosen {
        stdout-path = &uart1;
    };

    memory {
        reg = <0x80000000 0x20000000>;
    };

    reserved-memory {
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;

        linux,cma {
            compatible = "shared-dma-pool";
            reusable;
            size = <0x14000000>;
            linux,cma-default;
        };
    };

    backlight {
        compatible = "pwm-backlight";
        pwms = <&pwm1 0 5000000>;
        brightness-levels = <0 4 8 16 32 64 128 255>;
        default-brightness-level = <6>;
        status = "okay";
    };

    pxp_v4l2 {
        compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
        status = "okay";
    };

    regulators {
        compatible = "simple-bus";
        #address-cells = <1>;
        #size-cells = <0>;

        reg_can_3v3: regulator@0 {
            compatible = "regulator-fixed";
            reg = <0>;
            regulator-name = "can-3v3";
            regulator-min-microvolt = <3300000>;
            regulator-max-microvolt = <3300000>;
            gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
        };

        reg_sd1_vmmc: regulator@1 {
            compatible = "regulator-fixed";
            regulator-name = "VSD_3V3";
            regulator-min-microvolt = <3300000>;
            regulator-max-microvolt = <3300000>;
            gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
            enable-active-high;
        };

        reg_gpio_dvfs: regulator-gpio {
            compatible = "regulator-gpio";
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_dvfs>;
            regulator-min-microvolt = <1300000>;
            regulator-max-microvolt = <1400000>;
            regulator-name = "gpio_dvfs";
            regulator-type = "voltage";
            gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
            states = <1300000 0x1 1400000 0x0>;
        };
    };

    sound {
        compatible = "fsl,imx6ul-evk-wm8960",
               "fsl,imx-audio-wm8960";
        model = "wm8960-audio";
        cpu-dai = <&sai2>;
        audio-codec = <&codec>;
        asrc-controller = <&asrc>;
        codec-master;
        gpr = <&gpr 4 0x100000 0x100000>;
        /*
                 * hp-det = ;
         * hp-det-pin: JD1 JD2  or JD3
         * hp-det-polarity = 0: hp detect high for headphone
         * hp-det-polarity = 1: hp detect high for speaker
         */
        hp-det = <3 0>;
        hp-det-gpios = <&gpio5 4 0>;
        mic-det-gpios = <&gpio5 4 0>;
        audio-routing =
            "Headphone Jack", "HP_L",
            "Headphone Jack", "HP_R",
            "Ext Spk", "SPK_LP",
            "Ext Spk", "SPK_LN",
            "Ext Spk", "SPK_RP",
            "Ext Spk", "SPK_RN",
            "LINPUT2", "Mic Jack",
            "LINPUT3", "Mic Jack",
            "RINPUT1", "Main MIC",
            "RINPUT2", "Main MIC",
            "Mic Jack", "MICB",
            "Main MIC", "MICB",
            "CPU-Playback", "ASRC-Playback",
            "Playback", "CPU-Playback",
            "ASRC-Capture", "CPU-Capture",
            "CPU-Capture", "Capture";
    };

    spi4 {
        compatible = "spi-gpio";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_spi4>;
        /* pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; */
        status = "okay";
        gpio-sck = <&gpio5 11 0>;
        gpio-mosi = <&gpio5 10 0>;
        /* cs-gpios = <&gpio5 7 0>;*/    
         num-chipselects = <1>;
        #address-cells = <1>;
        #size-cells = <0>;

        gpio_spi: gpio_spi@0 {
            compatible = "fairchild,74hc595";
            gpio-controller;
            #gpio-cells = <2>;
            reg = <0>;
            registers-number = <1>;
            registers-default = /bits/ 8 <0x57>;
            spi-max-frequency = <100000>;
        };
    };
};

&cpu0 {
    arm-supply = <&reg_arm>;
    soc-supply = <&reg_soc>;
    dc-supply = <&reg_gpio_dvfs>;
};

&clks {
    assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <786432000>;
};

&csi {
    status = "okay";

    port {
        csi1_ep: endpoint {
            remote-endpoint = <&ov5640_ep>;
        };
    };
};



&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1
                 &pinctrl_enet1_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <200>;
    status = "okay";
};

&fec2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2
                 &pinctrl_enet1_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <200>;
    status = "okay";

    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            smsc,disable-energy-detect;
            reg = <0>;
        };

        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            smsc,disable-energy-detect;
            reg = <1>;
        };
    };
};

&flexcan1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan1>;
    xceiver-supply = <&reg_can_3v3>;
    status = "okay";
};

&flexcan2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan2>;
    xceiver-supply = <&reg_can_3v3>;
    status = "okay";
};

&gpc {
    fsl,cpu_pupscr_sw2iso = <0x1>;
    fsl,cpu_pupscr_sw = <0x0>;
    fsl,cpu_pdnscr_iso2sw = <0x1>;
    fsl,cpu_pdnscr_iso = <0x1>;
    fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
};

&i2c1 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c1>;
    status = "okay";

    mag3110@0e {
        compatible = "fsl,mag3110";
        reg = <0x0e>;
        position = <2>;
    };

    fxls8471@1e {
        compatible = "fsl,fxls8471";
        reg = <0x1e>;
        position = <0>;
        interrupt-parent = <&gpio5>;
        interrupts = <0 8>;
    };
};

&i2c2 {
    clock_frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c2>;
    status = "okay";

    codec: wm8960@1a {
        compatible = "wlf,wm8960";
        reg = <0x1a>;
        clocks = <&clks IMX6UL_CLK_SAI2>;
        clock-names = "mclk";
        wlf,shared-lrclk;
    };

    ov5640: ov5640@3c {
        compatible = "ovti,ov5640";
        reg = <0x3c>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_csi1>;
        clocks = <&clks IMX6UL_CLK_CSI>;
        clock-names = "csi_mclk";
        pwn-gpios = <&gpio_spi 6 1>;
        rst-gpios = <&gpio_spi 5 0>;
        csi_id = <0>;
        mclk = <24000000>;
        mclk_source = <0>;
        status = "okay";
        port {
            ov5640_ep: endpoint {
                remote-endpoint = <&csi1_ep>;
            };
        };
    };
};

&iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog_1>;
    imx6ul-evk {
        pinctrl_hog_1: hoggrp-1 {
            fsl,pins = <
                MX6UL_PAD_UART1_RTS_B__GPIO1_IO19    0x17059 /* SD1 CD */
                MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */
                MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */
            >;
        };

        pinctrl_csi1: csi1grp {
            fsl,pins = <
                MX6UL_PAD_CSI_MCLK__CSI_MCLK        0x1b088
                MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK    0x1b088
                MX6UL_PAD_CSI_VSYNC__CSI_VSYNC        0x1b088
                MX6UL_PAD_CSI_HSYNC__CSI_HSYNC        0x1b088
                MX6UL_PAD_CSI_DATA00__CSI_DATA02    0x1b088
                MX6UL_PAD_CSI_DATA01__CSI_DATA03    0x1b088
                MX6UL_PAD_CSI_DATA02__CSI_DATA04    0x1b088
                MX6UL_PAD_CSI_DATA03__CSI_DATA05    0x1b088
                MX6UL_PAD_CSI_DATA04__CSI_DATA06    0x1b088
                MX6UL_PAD_CSI_DATA05__CSI_DATA07    0x1b088
                MX6UL_PAD_CSI_DATA06__CSI_DATA08    0x1b088
                MX6UL_PAD_CSI_DATA07__CSI_DATA09    0x1b088
            >;
        };

        pinctrl_enet1: enet1grp {
            fsl,pins = <
                MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN    0x1b0b0
                MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER    0x1b0b0
                MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00    0x1b0b0
                MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01    0x1b0b0
                MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN    0x1b0b0
                MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00    0x1b0b0
                MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01    0x1b0b0
                MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1    0x4001b009
            >;
        };

        pinctrl_enet2: enet2grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO07__ENET2_MDC        0x1b0b0
                MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0
                MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN    0x1b0b0
                MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER    0x1b0b0
                MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00    0x1b0b0
                MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01    0x1b0b0
                MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN    0x1b0b0
                MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00    0x1b0b0
                MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01    0x1b0b0
                MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2    0x4001b009
            >;
        };

        pinctrl_flexcan1: flexcan1grp{
            fsl,pins = <
                MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX    0x1b020
                MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX    0x1b020
            >;
        };

        pinctrl_flexcan2: flexcan2grp{
            fsl,pins = <
                MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX    0x1b020
                MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX    0x1b020
            >;
        };

        pinctrl_i2c1: i2c1grp {
            fsl,pins = <
                MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
                MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
            >;
        };

        pinctrl_i2c2: i2c2grp {
            fsl,pins = <
                MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
                MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
            >;
        };

        pinctrl_lcdif_dat: lcdifdatgrp {
            fsl,pins = <
                MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x79
                MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x79
                MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x79
                MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x79
                MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x79
                MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x79
                MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x79
                MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x79
                MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x79
                MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x79
                MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x79
                MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x79
                MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x79
                MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x79
                MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x79
                MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x79
                MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x79
                MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x79
                MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x79
                MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x79
                MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x79
                MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x79
                MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x79
                MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x79
            >;
        };

        pinctrl_lcdif_ctrl: lcdifctrlgrp {
            fsl,pins = <
                MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x79
                MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79
                MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79
                MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79
            >;
        };

        pinctrl_pwm1: pwm1grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
            >;
        };

        pinctrl_qspi: qspigrp {
            fsl,pins = <
                MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK      0x70a1
                MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
                MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01   0x70a1
                MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02   0x70a1
                MX6UL_PAD_NAND_CLE__QSPI_A_DATA03     0x70a1
                MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B      0x70a1
            >;
        };

        pinctrl_sai2: sai2grp {
            fsl,pins = <
                MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x17088
                MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088
                MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA    0x11088
                MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA    0x11088
                MX6UL_PAD_JTAG_TMS__SAI2_MCLK        0x17088
            >;
        };

        pinctrl_tsc: tscgrp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO01__GPIO1_IO01    0xb0
                MX6UL_PAD_GPIO1_IO02__GPIO1_IO02    0xb0
                MX6UL_PAD_GPIO1_IO03__GPIO1_IO03    0xb0
                MX6UL_PAD_GPIO1_IO04__GPIO1_IO04    0xb0
            >;
        };

        pinctrl_uart1: uart1grp {
            fsl,pins = <
                MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
                MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
            >;
        };

        pinctrl_uart2: uart2grp {
            fsl,pins = <
                MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX    0x1b0b1
                MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX    0x1b0b1
                MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS    0x1b0b1
                MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS    0x1b0b1
            >;
        };

        pinctrl_uart2dte: uart2dtegrp {
            fsl,pins = <
                MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX    0x1b0b1
                MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX    0x1b0b1
                MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS    0x1b0b1
                MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS    0x1b0b1
            >;
        };

        pinctrl_usdhc1: usdhc1grp {
            fsl,pins = <
                MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x17059
                MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x10071
                MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
                MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
                MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
                MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
            >;
        };

        pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
            fsl,pins = <
                MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170b9
                MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100b9
                MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
                MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
                MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
                MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
            >;
        };

        pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
            fsl,pins = <
                MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170f9
                MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f9
                MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
                MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
                MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
                MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
            >;
        };

        pinctrl_usdhc2: usdhc2grp {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x10069
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
            >;
        };

        pinctrl_usdhc2_8bit: usdhc2grp_8bit {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x10069
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
                MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
                MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
                MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
                MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
            >;
        };

        pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x100b9
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x170b9
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
                MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
                MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
                MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
                MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
            >;
        };

        pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x100f9
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x170f9
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
                MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
                MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
                MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
                MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
            >;
        };

        pinctrl_wdog: wdoggrp {
            fsl,pins = <
                MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
            >;
        };
    };
};

&iomuxc_snvs {
    pinctrl-names = "default_snvs";
        pinctrl-0 = <&pinctrl_hog_2>;
        imx6ul-evk {
         /* paranoid Touch RESET */
        pinctrl_tsc_reset: tsc_reset {
            fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x10B0
                        >;
        };

        /* paranoid RGB RESET */
        ts_reset_hdmi_pin: ts_reset_hdmi_mux {
            fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x49
                        >;
        };

        pinctrl_hog_2: hoggrp-2 {
                        fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x80000000
                        >;
                };

        pinctrl_dvfs: dvfsgrp {
                        fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x79
                        >;
                };
        
        pinctrl_lcdif_reset: lcdifresetgrp {
                        fsl,pins = <
                                /* used for lcd reset */
                                MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09  0x79
                        >;
                };

        pinctrl_spi4: spi4grp {
                        fsl,pins = <
                                MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
                                MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
                        >;
                };

        pinctrl_sai2_hp_det_b: sai2_hp_det_grp {
                        fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04   0x17059
                        >;
                };
        /*enet1 reset paranoid*/
        pinctrl_enet1_reset: enet1resetgrp {
                        fsl,pins = <
                                /* used for enet1  reset */
                                MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x10B0      /* ENET1 RESET */
                        >;
                };

        /*enet2 reset paranoid*/
        pinctrl_enet2_reset: enet2resetgrp {
                        fsl,pins = <
                                /* used for enet2  reset */
                                MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x10B0     /* ENET2 RESET */      
                        >;
                };    
        };
};


&lcdif {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_lcdif_dat
             &pinctrl_lcdif_ctrl
             &pinctrl_lcdif_reset>;
    display = <&display0>;
    status = "okay";

    display0: display {
        bits-per-pixel = <16>;
        bus-width = <24>;

        display-timings {
            native-mode = <&timing0>;
            timing0: timing0 {
            clock-frequency = <9200000>;
            hactive = <480>;
            vactive = <272>;
            hfront-porch = <8>;
            hback-porch = <4>;
            hsync-len = <41>;
            vback-porch = <2>;
            vfront-porch = <4>;
            vsync-len = <10>;

            hsync-active = <0>;
            vsync-active = <0>;
            de-active = <1>;
            pixelclk-active = <0>;
            };
        };
    };
};

&pwm1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pwm1>;
    status = "okay";
};

&pxp {
    status = "okay";
};

&qspi {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_qspi>;
    status = "okay";
    ddrsmp=<0>;

    flash0: n25q256a@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "micron,n25q256a";
        spi-max-frequency = <29000000>;
        spi-nor,ddr-quad-read-dummy = <6>;
        reg = <0>;
    };
};

&sai2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sai2
             &pinctrl_sai2_hp_det_b>;

    assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
              <&clks IMX6UL_CLK_SAI2>;
    assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <0>, <12288000>;

    status = "okay";
};

&tsc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_tsc>;
    xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
    measure-delay-time = <0xffff>;
    pre-charge-time = <0xfff>;
    status = "okay";
};

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    status = "okay";
};

&uart2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart2>;
    fsl,uart-has-rtscts;
    /* for DTE mode, add below change */
    /* fsl,dte-mode; */
    /* pinctrl-0 = <&pinctrl_uart2dte>; */
    status = "okay";
};

&usbotg1 {
    dr_mode = "otg";
    srp-disable;
    hnp-disable;
    adp-disable;
    status = "okay";
};

&usbotg2 {
    dr_mode = "host";
    disable-over-current;
    status = "okay";
};

&usbphy1 {
    tx-d-cal = <0x5>;
};

&usbphy2 {
    tx-d-cal = <0x5>;
};

&usdhc1 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc1>;
    pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
    cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
    keep-power-in-suspend;
    enable-sdio-wakeup;
    vmmc-supply = <&reg_sd1_vmmc>;
    status = "okay";
};

&usdhc2 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc2_8bit>;
    pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
    bus-width = <8>;
    non-removable;
    status = "okay";
};

&wdog1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_wdog>;
    fsl,wdog_b;
};

最终设备树内容

/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/dts-v1/;

#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"

/ {
    model = "Freescale i.MX6 ULL 14x14 EVK Board";
    compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";

    chosen {
        stdout-path = &uart1;
    };

    memory {
        reg = <0x80000000 0x20000000>;
    };

    reserved-memory {
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;

        linux,cma {
            compatible = "shared-dma-pool";
            reusable;
            size = <0x14000000>;
            linux,cma-default;
        };
    };

    backlight {
        compatible = "pwm-backlight";
        pwms = <&pwm1 0 5000000>;
        brightness-levels = <0 4 8 16 32 64 128 255>;
        default-brightness-level = <7>;
        status = "okay";
    };

    pxp_v4l2 {
        compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
        status = "okay";
    };

    regulators {
        compatible = "simple-bus";
        #address-cells = <1>;
        #size-cells = <0>;

        reg_can_3v3: regulator@0 {
            compatible = "regulator-fixed";
            reg = <0>;
            regulator-name = "can-3v3";
            regulator-min-microvolt = <3300000>;
            regulator-max-microvolt = <3300000>;
            gpios = <&gpio_spi 3 GPIO_ACTIVE_LOW>;
        };

        reg_sd1_vmmc: regulator@1 {
            compatible = "regulator-fixed";
            regulator-name = "VSD_3V3";
            regulator-min-microvolt = <3300000>;
            regulator-max-microvolt = <3300000>;
            //gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
            enable-active-high;
        };

        /* zuozhongkai ADC vref 3.3V */
        reg_vref_adc: regulator@2 {
            compatible = "regulator-fixed";
            regulator-name = "VREF_3V3";
            regulator-min-microvolt = <3300000>;
            regulator-max-microvolt = <3300000>;
        };

        reg_gpio_dvfs: regulator-gpio {
            compatible = "regulator-gpio";
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_dvfs>;
            regulator-min-microvolt = <1300000>;
            regulator-max-microvolt = <1400000>;
            regulator-name = "gpio_dvfs";
            regulator-type = "voltage";
            gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
            states = <1300000 0x1 1400000 0x0>;
        };
    };

    sound {
        compatible = "fsl,imx6ul-evk-wm8960",
               "fsl,imx-audio-wm8960";
        model = "wm8960-audio";
        cpu-dai = <&sai2>;
        audio-codec = <&codec>;
        asrc-controller = <&asrc>;
        codec-master;
        gpr = <&gpr 4 0x100000 0x100000>;
        /*
                 * hp-det = ;
         * hp-det-pin: JD1 JD2  or JD3
         * hp-det-polarity = 0: hp detect high for headphone
         * hp-det-polarity = 1: hp detect high for speaker
         */
        hp-det = <3 0>;
        /*hp-det-gpios = <&gpio5 4 0>;
        mic-det-gpios = <&gpio5 4 0>;*/
        audio-routing =
            "Headphone Jack", "HP_L",
            "Headphone Jack", "HP_R",
            "Ext Spk", "SPK_LP",
            "Ext Spk", "SPK_LN",
            "Ext Spk", "SPK_RP",
            "Ext Spk", "SPK_RN",
            "LINPUT2", "Mic Jack",
            "LINPUT3", "Mic Jack",
            "RINPUT1", "Main MIC",
            "RINPUT2", "Main MIC",
            "Mic Jack", "MICB",
            "Main MIC", "MICB",
            "CPU-Playback", "ASRC-Playback",
            "Playback", "CPU-Playback",
            "ASRC-Capture", "CPU-Capture",
            "CPU-Capture", "Capture";
    };

    spi4 {
        compatible = "spi-gpio";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_spi4>;
        /* pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; */
        status = "okay";
        gpio-sck = <&gpio5 11 0>;
        gpio-mosi = <&gpio5 10 0>;
        /* cs-gpios = <&gpio5 7 0>;*/
        num-chipselects = <1>;
        #address-cells = <1>;
        #size-cells = <0>;

        gpio_spi: gpio_spi@0 {
            compatible = "fairchild,74hc595";
            gpio-controller;
            #gpio-cells = <2>;
            reg = <0>;
            registers-number = <1>;
            registers-default = /bits/ 8 <0x57>;
            spi-max-frequency = <100000>;
        };
    };
    
    /* paranoid dts leds linux自带led驱动的设备树*/
   /* dtsleds {
        compatible = "gpio-leds";
 
        led0 {
            label = "red";
            gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
            linux,default-trigger = "heartbeat";
            default-state = "on";
        };
    };*/

    /* zuozhongkai */
    alphaled {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "atkalpha-led";
        status = "okay";
        reg = < 0X020C406C 0X04        /* CCM_CCGR1_BAE             */
                0X020E0068 0X04        /* SW_MUX_GPIO1_IO03_BASE     */
                0X020E02F4 0X04        /* SW_PAD_GPIO1_IO03_BASE    */
                0X0209C000 0X04        /* GPIO1_DR_BASE             */
                0X0209C004 0X04>;    /* GPIO1_GDIR_BASE             */
    };

    gpioled {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "atkalpha-gpioled";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_led>;
        led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
        status = "okay";
    };

    beep {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "atkalpha-beep";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_beep>;
        beep-gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
        status = "okay";
    };


    key {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "atkalpha-key";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_key>;
        key-gpio = <&gpio1 18 GPIO_ACTIVE_LOW>; /* KEY0 */
        interrupt-parent = <&gpio1>;
        interrupts = <18 IRQ_TYPE_EDGE_BOTH>; /* FALLING RISING */
        status = "okay";
    };

    /* zuozhongkai dts keys linux自带的key驱动设备树 */
    gpio-keys {
        compatible = "gpio-keys";
        #address-cells = <1>;
        #size-cells = <0>;
        autorepeat;
        key0 {
            label = "GPIO Key Enter";
            linux,code = <KEY_ENTER>;
            gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
        };
    };

    /* paranoid sii902x reset */
    sii902x_reset: sii902x-reset {
        compatible = "gpio-reset";
        reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
        reset-delay-us = <100000>;
        #reset-cells = <0>;
        status = "disabled";
    };



};

&cpu0 {
    arm-supply = <&reg_arm>;
    soc-supply = <&reg_soc>;
    dc-supply = <&reg_gpio_dvfs>;
};

&clks {
    assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <786432000>;
};

&csi {
    status = "okay";

    port {
        csi1_ep: endpoint {
            remote-endpoint = <&ov5640_ep>;
        };
    };
};

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1
            &pinctrl_enet1_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <200>;
    status = "okay";
};

&fec2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2
                &pinctrl_enet2_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <200>;
    status = "okay";

    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            smsc,disable-energy-detect;
            reg = <0>;
         };
 
        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            smsc,disable-energy-detect;
            reg = <1>;
        };
    };
};

&flexcan1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_flexcan1>;
    xceiver-supply = <&reg_can_3v3>;
    status = "okay";
};

&gpc {
    fsl,cpu_pupscr_sw2iso = <0x1>;
    fsl,cpu_pupscr_sw = <0x0>;
    fsl,cpu_pdnscr_iso2sw = <0x1>;
    fsl,cpu_pdnscr_iso = <0x1>;
    fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
};

&i2c1 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c1>;
    status = "okay";

    ap3216c@1e {
        compatible = "alientek,ap3216c";
        reg = <0x1e>;
    };
};

&i2c2 {
    clock_frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c2>;
    status = "okay";

    codec: wm8960@1a {
        compatible = "wlf,wm8960";
        reg = <0x1a>;
        clocks = <&clks IMX6UL_CLK_SAI2>;
        clock-names = "mclk";
        wlf,shared-lrclk;
    };

    ov5640: ov5640@3c {
        compatible = "ovti,ov5640";
        reg = <0x3c>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_csi1>;
        clocks = <&clks IMX6UL_CLK_CSI>;
        clock-names = "csi_mclk";
        pwn-gpios = <&gpio_spi 6 1>;
        rst-gpios = <&gpio_spi 5 0>;
        csi_id = <0>;
        mclk = <24000000>;
        mclk_source = <0>;
        status = "disabled";
        port {
            ov5640_ep: endpoint {
                remote-endpoint = <&csi1_ep>;
            };
        };
    };

    /* paranoid FT5406/FT5426 */
    ft5426: ft5426@38 {
        compatible = "edt,edt-ft5426","edt,edt-ft5406";
        reg = <0x38>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_tsc
                    &pinctrl_tsc_reset >; 
        interrupt-parent = <&gpio1>; 
        interrupts = <9 0>; 
        reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;  
        interrupt-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; 
        status = "okay";
    };

    gt9147:gt9147@14 {
        compatible = "goodix,gt9147", "goodix,gt9xx";
        reg = <0x14>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_tsc
                    &pinctrl_tsc_reset >; 
        interrupt-parent = <&gpio1>; 
        interrupts = <9 0>; 
        reset-gpios  = <&gpio5 9 GPIO_ACTIVE_LOW>;
        interrupt-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; 
        status = "disable";  /* 如果需要改为okay */
    };

    /* zuozhongkai sill902x,如果需要HDMI就将status改为okay即可  */
    /*
    sii902x: sii902x@39 {
        compatible = "SiI,sii902x";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sii902x>;
        interrupt-parent = <&gpio1>;
        interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
        irq-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
        mode_str = "1280x720M@60";
        bits-per-pixel = <16>;
        resets = <&sii902x_reset>;
        reg = <0x39>;
        status = "disable"; 
    };*/
};

&iomuxc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog_1>;
    imx6ul-evk {
        pinctrl_hog_1: hoggrp-1 {
            fsl,pins = <
                MX6UL_PAD_UART1_RTS_B__GPIO1_IO19    0x17059 /* SD1 CD */
                MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */
                /* MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 SD1 RESET */
                MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x13058    /* USB_OTG1_ID */
            >;
        };
        /* paranoid LED */
        pinctrl_led: ledgrp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0x10B0 /* LED0 */
            >;
        };
        
        /* paranoid BEEP */
        pinctrl_beep: beepgrp {
            fsl,pins = <
                MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x10B0 /* beep */    
            >;
        };

        /* paranoid KEY */
        pinctrl_key: keygrp {
            fsl,pins = <
                MX6UL_PAD_UART1_CTS_B__GPIO1_IO18        0xF080    /* KEY0 */
            >;
        };        

        /* paranoid ECSPI */
        pinctrl_ecspi3: icm20608 {
            fsl,pins = < 
                MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20        0x10b0    /* CS */
                MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b1    /* SCLK */
                MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO        0x10b1    /* MISO */
                MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI        0x10b1    /* MOSI */
            >;
        };

        /* paranoid HDMI RGB */
        pinctrl_hdmi_dat: hdmidatgrp {
            /* do not change the pimux vlaue on alpaha and mini board*/
            fsl,pins = <
                MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x49
                MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x49
                MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x49
                MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x49
                MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x49
                MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x49
                MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x49
                MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x49
                MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x49
                MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x49
                MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x49
                MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x49
                MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x49
                MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x49
                MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x49
                MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x51
                MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x49
                MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x49
                MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x49 
                MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x49
                MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x49
                MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x49
                MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x49
                MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x49
            >;
        };

        /* paranoid HDMI RGB */
        pinctrl_hdmi_ctrl: hdmictrlgrp {
            fsl,pins = <
                MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x49
                MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x49
                MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x49
                MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x49
            >;
        };

        /* paranoid SII902X  INT*/
        pinctrl_sii902x: hdmigrp-1 {
            fsl,pins = <
                /*MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x11*/
            >;
        };

        /* paranoid PWM3 GPIO1_IO04 */
        pinctrl_pwm3: pwm3grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO04__PWM3_OUT   0x110b0
            >;
        };

        /* zuozhongkai ADC1_CH1 GPIO1_IO01 */
        pinctrl_adc1: adc1grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO01__GPIO1_IO01   0xb0 
            >;
        };

        pinctrl_csi1: csi1grp {
            fsl,pins = <
                MX6UL_PAD_CSI_MCLK__CSI_MCLK        0x1b088
                MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK    0x1b088 
                MX6UL_PAD_CSI_VSYNC__CSI_VSYNC        0x1b088
                MX6UL_PAD_CSI_HSYNC__CSI_HSYNC        0x1b088
                MX6UL_PAD_CSI_DATA00__CSI_DATA02    0x1b088
                MX6UL_PAD_CSI_DATA01__CSI_DATA03    0x1b088
                MX6UL_PAD_CSI_DATA02__CSI_DATA04    0x1b088
                MX6UL_PAD_CSI_DATA03__CSI_DATA05    0x1b088
                MX6UL_PAD_CSI_DATA04__CSI_DATA06    0x1b088
                MX6UL_PAD_CSI_DATA05__CSI_DATA07    0x1b088
                MX6UL_PAD_CSI_DATA06__CSI_DATA08    0x1b088
                MX6UL_PAD_CSI_DATA07__CSI_DATA09    0x1b088
            >;
        };

        pinctrl_enet1: enet1grp {
            fsl,pins = <
                MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN    0x1b0b0
                MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER    0x1b0b0
                MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00    0x1b0b0
                MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01    0x1b0b0
                MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN    0x1b0b0
                MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00    0x1b0b0
                MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01    0x1b0b0
                MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1    0x4001b009
            >;
        };

        pinctrl_enet2: enet2grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO07__ENET2_MDC        0x1b0b0
                MX6UL_PAD_GPIO1_IO06__ENET2_MDIO    0x1b0b0 
                MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN    0x1b0b0
                MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER    0x1b0b0
                MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00    0x1b0b0
                MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01    0x1b0b0
                MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN    0x1b0b0
                MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00    0x1b0b0
                MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01    0x1b0b0
                MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2    0x4001b009 
            >;
        };
        
        pinctrl_flexcan1: flexcan1grp{
            fsl,pins = <
                MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX    0x1b020
                MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX    0x1b020
            >;
        };

        pinctrl_flexcan2: flexcan2grp{
            fsl,pins = <
                /* MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX    0x1b020 */
                /* MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX    0x1b020 */
            >;
        };

        pinctrl_i2c1: i2c1grp {
            fsl,pins = <
                MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
                MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 
            >;
        };

        pinctrl_i2c2: i2c2grp {
            fsl,pins = <
                MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0
                MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0
            >;
        };

        pinctrl_lcdif_dat: lcdifdatgrp {
            fsl,pins = <
                MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x49
                MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x49
                MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x49
                MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x49
                MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x49
                MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x49
                MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x49
                MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x49
                MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x49
                MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x49
                MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x49
                MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x49
                MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x49
                MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x49
                MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x49
                MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x49
                MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x49
                MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x49
                MX6UL_PAD_LCD_DATA18__LCDIF_DATA18  0x49 
                MX6UL_PAD_LCD_DATA19__LCDIF_DATA19  0x49
                MX6UL_PAD_LCD_DATA20__LCDIF_DATA20  0x49
                MX6UL_PAD_LCD_DATA21__LCDIF_DATA21  0x49
                MX6UL_PAD_LCD_DATA22__LCDIF_DATA22  0x49
                MX6UL_PAD_LCD_DATA23__LCDIF_DATA23  0x49
            >;
        };

        pinctrl_lcdif_ctrl: lcdifctrlgrp {
            fsl,pins = <
                MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x79
                MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x79
                MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x79
                MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x79
            >;
        };

        pinctrl_pwm1: pwm1grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
            >;
        };

        pinctrl_qspi: qspigrp {
            fsl,pins = <
                MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK      0x70a1
                MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1
                MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01   0x70a1
                MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02   0x70a1
                MX6UL_PAD_NAND_CLE__QSPI_A_DATA03     0x70a1
                MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B      0x70a1
            >;
        };

        pinctrl_sai2: sai2grp {
            fsl,pins = <
                MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x17088
                MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088
                MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA    0x11088
                MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA    0x11088
                MX6UL_PAD_JTAG_TMS__SAI2_MCLK        0x17088
            >;
        };

        pinctrl_tsc: tscgrp {
            fsl,pins = <
                /* 7寸RGB屏幕,FT5426 */
                /* MX6UL_PAD_GPIO1_IO09__GPIO1_IO09    0xF080     */    /* TSC_INT */

                /* 7寸RGB屏幕,GT9147 */
                /* MX6UL_PAD_GPIO1_IO09__GPIO1_IO09    0x10B0     */    /* TSC_INT */
            
            >;
        };

        pinctrl_uart1: uart1grp {
            fsl,pins = <
                MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
                MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
            >;
        };

        pinctrl_uart2: uart2grp {
            fsl,pins = <
                /* MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX    0x1b0b1 */
                /* MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX    0x1b0b1 */
                MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS    0x1b0b1
                MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS    0x1b0b1
            >;
        };

        pinctrl_uart2dte: uart2dtegrp {
            fsl,pins = <
                /* MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX    0x1b0b1 */
                /* MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX    0x1b0b1 */
                /* MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS    0x1b0b1 */
                /* MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS    0x1b0b1 */
            >; 
        };
    
        /* zuozhongkai */
        pinctrl_uart3: uart3grp {
            fsl,pins = <
                MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX        0X1b0b1
                MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX        0X1b0b1
            >;
        };


        pinctrl_usdhc1: usdhc1grp {
            fsl,pins = <
                MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x17059
                MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f1
                MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
                MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
                MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
                MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
            >;
        };

        pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
            fsl,pins = <
                MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170b9
                MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f1
                MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
                MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
                MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
                MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
            >;
        };

        pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
            fsl,pins = <
                MX6UL_PAD_SD1_CMD__USDHC1_CMD     0x170f9
                MX6UL_PAD_SD1_CLK__USDHC1_CLK     0x100f1
                MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
                MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
                MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
                MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
            >;
        };

        pinctrl_usdhc2: usdhc2grp {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x10069
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
            >;
        };

        pinctrl_usdhc2_8bit: usdhc2grp_8bit {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x10069
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x17059
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
                MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
                MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
                MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
                MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
            >;
        };

        pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x100b9
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x170b9
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
                MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
                MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
                MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
                MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
            >;
        };

        pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {
            fsl,pins = <
                MX6UL_PAD_NAND_RE_B__USDHC2_CLK     0x100f9
                MX6UL_PAD_NAND_WE_B__USDHC2_CMD     0x170f9
                MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
                MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
                MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
                MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
                MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
                MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
                MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
                MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
            >;
        };

        pinctrl_wdog: wdoggrp {
            fsl,pins = <
                MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
            >;
        };
    };
};

&iomuxc_snvs {
    pinctrl-names = "default_snvs";
        pinctrl-0 = <&pinctrl_hog_2>;
        imx6ul-evk {

        /* zuozhongkai Touch RESET */
        pinctrl_tsc_reset: tsc_reset {
            fsl,pins = <
                                 MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x10B0
                        >;
        };

        /* zuozhongkai RGB RESET */
        ts_reset_hdmi_pin: ts_reset_hdmi_mux {
            fsl,pins = <
                                 MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x49
                        >;
        };

        pinctrl_hog_2: hoggrp-2 {
                        fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x80000000
                        >;
                };

        pinctrl_dvfs: dvfsgrp {
                        fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x79
                        >;
                };
        
        pinctrl_lcdif_reset: lcdifresetgrp {
                        fsl,pins = <
                                /* used for lcd reset */
                                /* MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09  0x79 */
                        >;
                };

        pinctrl_spi4: spi4grp {
                        fsl,pins = <
                                MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10        0x70a1
                                MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11        0x70a1
                        >;
                };

        pinctrl_sai2_hp_det_b: sai2_hp_det_grp {
                        fsl,pins = <
                                MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04   0x17059
                        >;
                };

        /*enet1 reset zuozhongkai*/
        pinctrl_enet1_reset: enet1resetgrp {
                        fsl,pins = <
                                /* used for enet1  reset */
                                MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x10B0      /* ENET1 RESET */
                        >;
                };

        /*enet2 reset zuozhongkai*/
        pinctrl_enet2_reset: enet2resetgrp {
                        fsl,pins = <
                                /* used for enet2  reset */
                                MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x10B0     /* ENET2 RESET */      
                        >;
                };
        };
};


&lcdif {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_lcdif_dat
             &pinctrl_lcdif_ctrl>;

    display = <&display0>;
    status = "okay"; 

    /* 7寸1024*600 */
    display0: display {
        bits-per-pixel = <24>;
        bus-width = <24>;

        display-timings {
            native-mode = <&timing0>;
            timing0: timing0 {
            clock-frequency = <51200000>;
            hactive = <1024>;
            vactive = <600>;
            hfront-porch = <160>;
            hback-porch = <140>;
            hsync-len = <20>;
            vback-porch = <20>;
            vfront-porch = <12>;
            vsync-len = <3>;

            hsync-active = <0>;
            vsync-active = <0>;
            de-active = <1>;
            pixelclk-active = <0>;
            };
        };
    };

    /* 4.3寸480*272 */
    /* display0: display {
        bits-per-pixel = <24>;
        bus-width = <24>;

        display-timings {
            native-mode = <&timing0>;
            timing0: timing0 {
            clock-frequency = <9000000>;
            hactive = <480>;
            vactive = <272>;
            hfront-porch = <5>;
            hback-porch = <40>;
            hsync-len = <1>;
            vback-porch = <8>;
            vfront-porch = <8>;
            vsync-len = <1>;

            hsync-active = <0>;
            vsync-active = <0>;
            de-active = <1>;
            pixelclk-active = <0>;
            };
        };
    };*/

    /* 4.3寸800*480 */
    /* display0: display {
        bits-per-pixel = <24>;
        bus-width = <24>;

        display-timings {
            native-mode = <&timing0>;
            timing0: timing0 {
            clock-frequency = <31000000>;
            hactive = <800>;
            vactive = <480>;
            hfront-porch = <40>;
            hback-porch = <88>;
            hsync-len = <48>;
            vback-porch = <32>;
            vfront-porch = <13>;
            vsync-len = <3>;

            hsync-active = <0>;
            vsync-active = <0>;
            de-active = <1>;
            pixelclk-active = <0>;
            };
        };
    };*/

};

&pwm1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pwm1>;
    status = "okay";
};

/* zuozhongkai PWM3 */
&pwm3 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_pwm3>;
    clocks = <&clks IMX6UL_CLK_PWM3>,
             <&clks IMX6UL_CLK_PWM3>;
    status = "disable";
};

/* zuozhongkai ADC1 */
&adc1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_adc1>;
    num-channels = <2>;
    vref-supply = <&reg_vref_adc>;
    status = "okay";    
};


&pxp {
    status = "okay";
};

&qspi {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_qspi>;
    status = "okay";
    ddrsmp=<0>;

    flash0: n25q256a@0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "micron,n25q256a";
        spi-max-frequency = <29000000>;
        spi-nor,ddr-quad-read-dummy = <6>;
        reg = <0>;
    };
};

&sai2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_sai2
             &pinctrl_sai2_hp_det_b>;

    assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,
              <&clks IMX6UL_CLK_SAI2>;
    assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
    assigned-clock-rates = <0>, <12288000>;

    status = "okay";
};

&tsc {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_tsc>;
    /*xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;*/
    measure-delay-time = <0xffff>;
    pre-charge-time = <0xfff>;
    status = "disable";
};

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart1>;
    status = "okay";
};

/* zuozhongkai */
&uart3 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart3>;
    status = "okay";
};

&usbotg1 {
    dr_mode = "otg";
    srp-disable;
    hnp-disable;
    adp-disable;
    status = "okay";
};

&usbotg2 {
    dr_mode = "host";
    disable-over-current;
    status = "okay";
};

&usbphy1 {
    tx-d-cal = <0x5>;
};

&usbphy2 {
    tx-d-cal = <0x5>;
};

&usdhc1 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc1>;
    pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
    cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
    keep-power-in-suspend;
    enable-sdio-wakeup;
    vmmc-supply = <&reg_sd1_vmmc>;
    status = "okay";
    no-1-8-v;
};

&usdhc2 {
    pinctrl-names = "default", "state_100mhz", "state_200mhz";
    pinctrl-0 = <&pinctrl_usdhc2_8bit>;
    pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
    pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
    bus-width = <8>;
    non-removable;
    status = "okay";
};

&wdog1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_wdog>;
    fsl,wdog_b;
};

/* zuozhongkai  */
&ecspi3 {
    fsl,spi-num-chipselects = <1>;
    cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; /* cant't use cs-gpios! */
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi3>;
    status = "okay";

    spidev: icm20608@0 {
        compatible = "alientek,icm20608";
        spi-max-frequency = <8000000>;
        reg = <0>;
    };    
};


最终结果

网络驱动测试

修改好设备树和 Linux 内核以后重新编译一下,
cp arch/arm/boot/zImage /home/alientek/linux/tftp/ -f
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb /home/alientek/linux/tftp/ -f
得到新的 zImage 镜像文件和 imx6ullalientek-emmc.dtb 设备树文件,使用网线将 I.MX6U-ALPHA 开发板的两个网口与路由器或者电脑连接起来,最后使用新的文件启动 Linux 内核。启动以后使用“ifconfig”命令查看一下当前活动的网卡有哪些,结果如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第27张图片

输入命令“ifconfig -a”来查看一下开发板中存在的所有网卡,结果如图 所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第28张图片

eth0 和 eth1 才网络接口的网卡,其中eth0 对应于 ENET2, eth1 对应于 ENET1。使用如下命令依次打开 eth0 和 eth1 这两个网卡:

ifconfig eth0 up
ifconfig eth1 up

网卡的打开过程如图 所示:

从图中可以看到“Generic PHY”字样,说明当前的网络驱动使用的就是我们使能的 PHY 驱动。
再次输入“ifconfig”命令来查看一下当前活动的网卡,

可以看出,此时 eth0 和 eth1 两个网卡都已经打开,并且工作正常,但是这两个网卡都还没有 IP 地址,所以不能进行ping 等操作。使用如下命令给两个网卡配置IP 地址:
ifconfig eth0 XXXXXXX
ifconfig eth1 XXXXXXXX
上述命令配置 eth0 和 eth1 这两个网卡的 IP 地址分别为 XXXX 和 XXXXX,注意 IP 地址选择的合理性,一定要和自己的电脑处于同一个网段内,并且没有被其他的设备占用!设置好以后,使用“ping”命令来 ping 一下自己的主机,如果能 ping 通那说明网络驱动修改成功!比如我的Ubuntu 主机 IP 地址为 192.168.10.100,使用如下命令ping 一下:
ping 192.168.10.100
结果如图所示:
Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)_第29张图片

可以看出, ping 成功,说明网络驱动修改成功!我们在后面的构建根文件系统和 Linux 驱动开发中就可以使用网络调试代码啦。

你可能感兴趣的:(Linux驱动V2.0,#,移植,驱动开发,linux,c语言,驱动开发,arm,嵌入式)