• I.MX6UL的uboot移植


    1.5U-Boot移植

    imx6ull\01_Source_Code\04、NXP官方原版Uboot和Linux\uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2

    chmod 777 uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
    tar -xvf uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2
    cd uboot-imx-rel_imx_4.1.15_2.1.0_ga 
    
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_evk_emmc_defconfig 
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    mx6ull_14x14_emmc.sh 编译直接执行./mx6ull_14x14_emmc.sh

    #!/bin/bash 
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean 
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- 
    mx6ull_14x14_evk_emmc_defconfig 
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1.5.1 制作自己的uboot镜像
    cd configs 
    cp mx6ull_14x14_evk_emmc_defconfig  mx6ull_alientek_emmc_defconfig 
    
    • 1
    • 2

    mx6ull_alientek_emmc_defconfig 在第一行和第四行做了修改

    CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6ull_alientek_ 
    emmc/imximage.cfg,MX6ULL_EVK_EMMC_REWORK"   #修改
    CONFIG_ARM=y 
    CONFIG_ARCH_MX6=y 
    CONFIG_TARGET_MX6ULL_ALIENTEK_EMMC=y        #修改
    CONFIG_CMD_GPIO=y 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1.5.2 添加开发板对应的头文件

    ​ 在iclude/configs下添加mx6ull_alientek_emmc.h

    ​ mx6ull_alientek_emmc.h有很多宏定义,用于配置uboot,需要去做一些修改。

    ​ CONFIF开头的宏定义用于配置和裁剪uboot,需要某个功能就CONFIG_XXX,不需要就去删除掉对应的宏就可以了。

    ​ 以 CONFIG_CMD开头的宏都是用于使能相应命令的,其他的以 CONFIG开头的宏都是完成一些配置功能

    cp include/configs/mx6ullevk.h mx6ull_alientek_emmc.h 
    
    • 1

    拷贝后修改

    #ifndef __MX6ULLEVK_CONFIG_H 
    #define __MX6ULLEVK_CONFIG_H
    
    • 1
    • 2

    #ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H 
    #define __MX6ULL_ALIENTEK_EMMC_CONFIG_H 
    
    • 1
    • 2
    1.5.3 添加开发板对应的板级文件夹
    # 复制文件board/freescale 
    cd board/freescale/
    cp mx6ullevk/ -r mx6ull_alientek_emmc
    
    cd mx6ull_alientek_emmc 
    mv mx6ullevk.c mx6ull_alientek_emmc.c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改mx6ull_alientek_emmc目录下的Makefile文件

    # (C) Copyright 2015 Freescale Semiconductor, Inc.
    #
    # SPDX-License-Identifier:	GPL-2.0+
    #
    
    obj-y  := mx6ull_alientek_emmc.o  #mx6ull_alientek_emmc.o修改为mx6ull_alientek_emmc.o
    
    extra-$(CONFIG_USE_PLUGIN) :=  plugin.bin
    $(obj)/plugin.bin: $(obj)/plugin.o
    	$(OBJCOPY) -O binary --gap-fill 0xff $< $@
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    修改mx6ull_alientek_emmc目录下的imximage.cfg文件

    PLUGIN board/freescale/mx6ullevk/plugin.bin 0x00907000 
    修改为 
    PLUGIN board/freescale/mx6ull_alientek_emmc /plugin.bin 0x00907000 
    
    • 1
    • 2
    • 3

    修改mx6ull_alientek_emmc目录下的Kconfig文件

    if TARGET_MX6ULL_ALIENTEK_EMMC
    
    config SYS_BOARD
    	default "mx6ull_alientek_emmc"
    
    config SYS_VENDOR
    	default "freescale"
    
    config SYS_SOC 
    	default "mx6"
    
    config SYS_CONFIG_NAME
    	default "mx6ull_alientek_emmc"
    
    endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    修改mx6ull_alientek_emmc目录下的MAINTAINERS文件

    MX6ULLEVK BOARD
    M:	Peng Fan 
    S:	Maintained
    F:	board/freescale/mx6ull_alientek_emmc/
    F:	include/configs/mx6ull_alientek_emmc.h
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1.5.4 修改U-Boot图形界面配置文件

    arch/arm/cpu/armv7/mx6/Kconfig

    1.在第207行加入以下内容:
    config TARGET_MX6ULL_ALIENTEK_EMMC 
        bool "Support mx6ull_alientek_emmc" 
        select MX6ULL 
        select DM 
        select DM_THERMAL 
    
    2.在最后一行的endif的前一行添加如下内容:
    source "board/freescale/mx6ull_alientek_emmc/Kconfig" 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1.5.5 使用新加的板子来配置编译uboot

    mx6ull_alientek_emmc.sh

    #!/bin/bash 
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean 
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig 
    make V=1  ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 
    
    • 1
    • 2
    • 3
    • 4
    chmod 777 mx6ull_alientek_emmc.sh  //给予可执行权限
    ./mx6ull_alientek_emmc.sh          //运行脚本编译uboot
    
    • 1
    • 2
    grep -nR "mx6ull_alientek_emmc.h" 
    //如果有很多文件引用了 mx6ull_alientek_emmc.h头文件,说明新板子加入成功
    
    • 1
    • 2

    默认的LCD驱动网络驱动在正电原子的I.MX6U-ALPHA的开发板上是有问题的,需要进行修改

    报错:
    arm-linux-gnueabihf-ld.bfd:u-boot.lds:1: ignoring invalid character `\350' in expression
    解决方法:
    在#define处加//注释,可能会被编译器认为此处存在转译从而引发编译链接错误,使用/* */*
    
    • 1
    • 2
    • 3
    • 4
    1.5.6 LCD驱动修改

    image-20221114222126420

    board/freescale/mx6ull_alientek_emmc/include/mx6ull_alientek_emmc.c,修改为对应的LCD参数

    目前的LCD是正点原子4.3存的屏幕 分辨率800x480 触摸驱动:GT9147 IIC接口

    struct display_info_t const displays[] = {{
    	.bus = MX6UL_LCDIF1_BASE_ADDR, 
    	.addr = 0,
    	.pixfmt = 24,    /* RGB888,此时就是24位 */
    	.detect = NULL,
    	.enable	= do_enable_parallel_lcd,
    	.mode	= {
    		.name		   = "ATK-LCD-4.3-800X480",    /* LCD名字 */
    		.xres           = 800,           /* x轴像素数量 */
    		.yres           = 480,			/* Y轴像素数量 */
    		.pixclock       = 10119,         /* 每个像素时钟的时钟周期长度,为ps*/
    		.left_margin    = 210,           /* HBP 水平同步后肩*/
    		.right_margin   = 46,			/* HFP 水平同步前肩*/
    		.upper_margin   = 22,			/* VBP 垂直同步后肩*/
    		.lower_margin   = 23,			/* VFP 垂直同步后肩*/
    		.hsync_len      = 20,			/* HSPW 行同步脉宽*/
    		.vsync_len      = 3,			/* VSPW 垂直同步脉宽*/
    		.sync           = 0,			
    		.vmode          = FB_VMODE_NONINTERLACED   /* 不使用隔行扫描 */
    } } };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ​ board/freescale/mx6ull_alientek_emmc/include/mx6ull_alientek_emmc.h,如果在mx6ull_alientek_emmc.c文件里面更换了name,需要对panel进行替换

    panel=TFT43AB 
    修改为
    panel=ATK-LCD-4.3-800X480 
    
    • 1
    • 2
    • 3

    ​ 之前的环境变量会保存在EMMC中,uboot启动会先从EMMC中读取环境变量,需要修改

    setenv panel ATK-LCD-4.3-800X480 
    saveenv
    
    • 1
    • 2
    1.5.7 网络驱动修改

    网络芯片为v2.4后版本,为SR8201F

    ENET1网络驱动
    1.ENET1复位引脚初始化    连接在SNVS_TAMPER7引脚
    2.SR8201F的器件 ID 0x2
    3.SR8201F驱动 
    
    ENET2网络驱动
    1.ENET2复位引脚初始化    连接在SNVS_TAMPER8引脚
    2.SR8201F的器件 ID  0x1
    3.SR8201F驱动 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ​ board/freescale/mx6ull_alientek_emmc/include/mx6ull_alientek_emmc.h

    修改ENET1网络的PHY地址,修改ENET2网络PHY的地址以及使能 REALTEK公司的 PHY驱动


    CONFIG_PHY_MICREL,此宏用于使能 uboot中 Micrel公司的 PHY驱动,KSZ8081这颗 PHY芯片就是 Micrel公司生产的,不过 Micrel已经被 Microchip收购了。如果要使用 SR8201F,那么就得将 CONFIG_PHY_MICREL改为 CONFIG_PHY_REALTEK。因为 SR8201F就是 Pin to Pin替换 Realtek的 RTL8201F的,因此可以直接使用 Realtek的相关驱动

    #ifdef CONFIG_CMD_NET       /*使能网络的dhcp以及ping命令等*/
    #define CONFIG_CMD_PING
    #define CONFIG_CMD_DHCP
    #define CONFIG_CMD_MII
    #define CONFIG_FEC_MXC
    #define CONFIG_MII
    #define CONFIG_FEC_ENET_DEV		1  /*指定所使用的网口,为0的时候使用ENET1,为1的时候使用ENTT2,默认为1,也就是选择ENET2*/
    
    #if (CONFIG_FEC_ENET_DEV == 0)
    #define IMX_FEC_BASE			ENET_BASE_ADDR  /*ENET接口的寄存器首地址*/
    #define CONFIG_FEC_MXC_PHYADDR          0x2      /*网口PHY芯片的地址*/
    #define CONFIG_FEC_XCV_TYPE             RMII     /*PHY芯片所使用的接口类型,使用的时RMII接口*/
    #elif (CONFIG_FEC_ENET_DEV == 1)
    #define IMX_FEC_BASE			ENET2_BASE_ADDR
    #define CONFIG_FEC_MXC_PHYADDR	 0x1
    #define CONFIG_FEC_XCV_TYPE		 RMII
    #endif
    #define CONFIG_ETHPRIME			"FEC"
    
    #define CONFIG_PHYLIB
    #define CONFIG_PHY_REALTK                  /* CONFIG_PHY_MICREL修改为CONFIG_PHY_REALTK*/
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    网络复位引脚的驱动修改

    board/freescale/mx6ull_alientek_emmc/include/mx6ull_alientek_emmc.c

    修改ENET的引脚

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BK7rEnv8-1668521272641)(https://cdn.jsdelivr.net/gh/Yin-Liang/mdImage/img/image-20221114232545498.png)]

    删除iomux_v3_cfg_t const iox_pads的结构体

    删除iox74lv_init函数(74LV595的初始化函数)和iox74lv_set函数(控制74LV595的IO输出)

    删除board_init中的 imx_iomux_v3_setup_multiple_pads 和 iox74lv_init这两个函数,这是用来初始化
    74lv595的 GPIO

    结构体数组 fec1_pads和 fec2_pads是 ENET1和 ENET2这两个网口的 IO配置参数,在这
    两个数组中添加两个网口的复位 IO配置参数

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UAe22WfQ-1668521272641)(https://cdn.jsdelivr.net/gh/Yin-Liang/mdImage/img/image-20221114233608004.png)]

    在函数 setup_iomux_fec中添加网络复位 IO的初始化代码,并且复位一下 PHY芯片

    static void setup_iomux_fec(int fec_id) 
    { 
        if (fec_id == 0) 
        { 
     
            imx_iomux_v3_setup_multiple_pads(fec1_pads, 
                             ARRAY_SIZE(fec1_pads)); 
     
            gpio_direction_output(ENET1_RESET, 1);   /* 设置为输出 */
            gpio_set_value(ENET1_RESET, 0);          /* 设置为0复位 */
            mdelay(20); 
            gpio_set_value(ENET1_RESET, 1);          /* 设置为1,1的情况下正常工作 */
        } 
        else 
        { 
            imx_iomux_v3_setup_multiple_pads(fec2_pads, 
                             ARRAY_SIZE(fec2_pads)); 
            gpio_direction_output(ENET2_RESET, 1); 
            gpio_set_value(ENET2_RESET, 0); 
            mdelay(20); 
            gpio_set_value(ENET2_RESET, 1); 
        } 
       mdelay(150); /* 复位结束后至少延时 150ms才能正常使用,这是SR8201手册的要求*/ 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    烧写uboot.bin后

    setenv ipaddr 192.168.10.50      //开发板 IP地址 
    setenv ethaddr b8:ae:1d:01:00:00 //开发板网卡 MAC地址 
    setenv gatewayip 192.168.10.1    //开发板默认网关 
    setenv netmask 255.255.255.0     //开发板子网掩码 
    setenv serverip 192.168.10.100   //服务器地址,也就是 Ubuntu地址 
    saveenv                          //保存环境变量 
    
    ping 192.168.10.100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.5.8 修改uboot启动信息的名字

    Board: MX6ULL 14x14 EVK 改为 MX6ULL ALIENTEK EMMC

    board/freescale/mx6ull_alientek_emmc/include/mx6ull_alientek_emmc.c

    int checkboard(void) 
    { 
        if (is_mx6ull_9x9_evk()) 
            puts("Board: MX6ULL 9x9 EVK\n"); 
        else 
            puts("Board: MX6ULL ALIENTEK EMMC\n"); 
     
        return 0; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1.5.9 bootcmd和 bootargs环境变量

    mx6ull_alientek_emmc.h中的宏 CONFIG_EXTRA_ENV_SETTINGS保存着环境变量的默认值

    ​ bootcmd保存uboot默认命令,uboot倒计时后就去执行bootcmd的命令,这些命令一般用来启动linux内核,比如读取EMMCA或者NAND Flash中的linux镜像文件和设备树文件到DRAM,然后启动linux内核。可以在uboot启动后进入命令行来设置bootcmd环境变量的值。

    ​ 如果EMMC或者NAND中没有保存bootcmd的数值,就会使用默认值来设置bootcmd环境变量

    include/enc_default.h

    image-20221115201321887

    CONFIG_BOOTCOMMAND 的数值是用来设置bootcmd的默认值

    board/freescale/mx6ull_alientek_emmc/include/mx6ull_alientek_emmc.c

    /* CONFIG_BOOTCOMMAND 设置环境变量bootcmd的值*/
    #define CONFIG_BOOTCOMMAND \
    	   "run findfdt;" \                 
    	   /* 用来查找开发板对应的设备树文件.dtb,设置fdt_file为对应的dtb */
    	   "mmc dev ${mmcdev};" \          
    	   /* 用于切换mmc设备,mmcdev为1,这里切换到EMMC上 */
    	   "mmc dev ${mmcdev}; if mmc rescan; then " \  
    	   /* 查看是否有SD卡和EMMC存在,没有的话就跳转执行run netboot,这是一个自定义的环境变量,用来从网络启动linux。如果mmc存在从mmc启动 */
    		   "if run loadbootscript; then " \
    	  /* loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script} */
    	  /* loadbootscript=fatload mmc 1:1 0x80800000 boot.scr; */
    	  /*  loadbootscript就是从 mmc1的分区 1中读取文件 boot.src到 DRAM的 0X80800000处 */
    			   "run bootscript; " \
          /* 加载boot.src成功,就运行bootscript环境变量 */
    		   "else " \
    			   "if run loadimage; then " \
    	 /* 如果boot.src找不到。就去执行loadimage操作 */
    	 /* loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}  */
    	 /* loadimage=fatload mmc 1:1 0x80800000 zImage */
    	 /* 从 mmc1的分区中读取 zImage到内存的 0X80800000处,而 mmc1
    的分区 1中存在 zImage */
    				   "run mmcboot; " \
    	/* 加载linux镜像文件zImage成功之后,就去运行环境变量mmcboot */
    			   "else run netboot; " \
    			   "fi; " \
    		   "fi; " \
    	   "else run netboot; fi"
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    run mmcboot

    "mmcboot=echo Booting from mmc ...; " \
    /* 输出信息 Booting from mmc ... */
    		"run mmcargs; " \
    		/* 运行环境变量mmcargs,用来设置bootargs */
    		"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
    			"if run loadfdt; then " \
    			/* loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}*/
    			/* loadfdt=fatload mmc 1:1 0x83000000 imx6ull-14x14-evk.dtb  */
    			/* 从mmc1的分区1读取imx6ull-14x14-evk.dtb文件放到0x83000000 */
    				"bootz ${loadaddr} - ${fdt_addr}; " \
    			/* bootz 0x80800000 - 0x83000000 启动linux*/
    			"else " \
    				"if test ${boot_fdt} = try; then " \
    					"bootz; " \
    				"else " \
    					"echo WARN: Cannot load the DT; " \
    				"fi; " \
    			"fi; " \
    		"else " \
    			"bootz; " \
    		"fi;\0" \
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    CONFIG_BOOTCOMMAND 可以简化修改为

    #define CONFIG_BOOTCOMMAND \ 
        "mmc dev 1;" \      /*切换到EMMC*/
        "fatload mmc 1:1 0x80800000 zImage;" \  /* 读取Image到0x80000000 */
        "fatload mmc 1:1 0x83000000 imx6ull-alientek-emmc.dtb;" \  /* 读取设备树到0x83000000 */
        "bootz 0x80800000 - 0x83000000;" /*启动linux内核*/
    
    • 1
    • 2
    • 3
    • 4
    • 5

    或者在uboot中设置bootcmd的值

    setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000;' 
    
    • 1

    环境变量bootargs

    bootargs保存着uboot传递给Linux内核的参数,是由mmcargs决定的

    mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot} 
    mmcargs=setenv bootargs console= ttymxc0, 115200 root= /dev/mmcblk1p2 rootwait rw
    bootargs设置了很多参数的值,这些参数内核会使用到
    
    1.console 
    	设置linux终端或者叫控制台,通过什么设备来和linux进行交互,是串口还是LCD屏幕,一般设置串口来作为linux终端,通过SecureCRT与linux交互,设置console为ttymxc0,因为linux启动后,串口1在linux下的设备文件时/dev/ttymxc0  
    	,115200 是设置串口的波特率,设置串口1来作为终端,并且串口波特率为115200
    	
    2.root
    	用来设置根文件系统的位置,root= /dev/mmcblk1p2,在mmcblk1设备中的分区2。EMMC的核心板启动后由/dev/mmcblk0,/dev/mmcblk1,/dev/mmcblk0p1,/dev/mmcblk0p2,/dev/mmcblk1p1,/dev/mmcblk1p2
    	/dev/mmcblkx(x=0~n)表示 mmc设备,而/dev/mmcblkxpy(x=0~n,y=1~n)表示 mmc设备x的分区y
    	
    	/dev/mmcblk1p2表示EMMC的分区2
    	
    	rootwait表示等待mmc设备初始化完成以后再挂载,否则的话mmc还没有初始化完成就挂载根文件系统会出错。
    	rw表示根文件系统是可以读写的,不加rw只能在根文件系统中进行读操作,不能进行写操作。
    	
    3.rootfstype
    	指定根文件系统类型,如果根文件系统是ext无所谓,如果是yaffs jffs ubifs则必须设置这些选项,指定根文件系统的类型
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1.5.10 从EMMC启动和从网络启动linux系统

    EMMC启动 (emmc有zimage和dtb设备树)

    setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' 
    setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 
    imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000;' 
    saveenv
    
    boot(run bootcmd)  //启动内核
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    网络启动 (linux镜像文件和根文件系统存放在Ubuntu中,使用cp拷贝文件夹,通过nfs或者tftp来下载Image和设备树文件)

    setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw' 
    setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz 
    80800000 - 83000000' 
    saveenv 
    
    tftp下载zImage和 imx6ull-alientek-emmc.dtb
    
    启动linux内核
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.5.11 mx6ull_alientek_emmc.h
    /*
     * Copyright (C) 2016 Freescale Semiconductor, Inc.
     *
     * Configuration settings for the Freescale i.MX6UL 14x14 EVK board.
     *
     * SPDX-License-Identifier:	GPL-2.0+
     */
    #ifndef __MX6ULL_ALIENTEK_EMMC_CONFIG_H 
    #define __MX6ULL_ALIENTEK_EMMC_CONFIG_H 
    
    
    #include 
    #include 
    #include "mx6_common.h"
    #include 
    
    /* uncomment for PLUGIN mode support */
    /* #define CONFIG_USE_PLUGIN */
    
    /* uncomment for SECURE mode support */
    /* #define CONFIG_SECURE_BOOT */
    
    #ifdef CONFIG_SECURE_BOOT
    #ifndef CONFIG_CSF_SIZE
    #define CONFIG_CSF_SIZE 0x4000
    #endif
    #endif
    
    #define is_mx6ull_9x9_evk()	CONFIG_IS_ENABLED(TARGET_MX6ULL_9X9_EVK)
    
    #ifdef CONFIG_TARGET_MX6ULL_9X9_EVK
    #define PHYS_SDRAM_SIZE		SZ_256M
    #define CONFIG_BOOTARGS_CMA_SIZE   "cma=96M "
    #else
    #define PHYS_SDRAM_SIZE		SZ_512M     /* DRAM的大小 */
    #define CONFIG_BOOTARGS_CMA_SIZE   ""
    /* DCDC used on 14x14 EVK, no PMIC */
    #undef CONFIG_LDO_BYPASS_CHECK
    #endif
    
    /* SPL options */
    /* We default not support SPL
     * #define CONFIG_SPL_LIBCOMMON_SUPPORT
     * #define CONFIG_SPL_MMC_SUPPORT
     * #include "imx6_spl.h"
    */
    
    #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
    
    #define CONFIG_DISPLAY_CPUINFO     /* uboot启动的时候输出CPU时间 */
    #define CONFIG_DISPLAY_BOARDINFO   /* uboot启动的时候输出板子时间 */
    
    /* Size of malloc() pool */
    #define CONFIG_SYS_MALLOC_LEN		(16 * SZ_1M) /*设置malloc内存池大小,设置为16MB*/
    
    #define CONFIG_BOARD_EARLY_INIT_F     /*board_init_f函数就会调用board_early_init_f函数*/
    #define CONFIG_BOARD_LATE_INIT        /*board_init_r函数就会调用board_late_init函数*/
    
    #define CONFIG_MXC_UART
    #define CONFIG_MXC_UART_BASE		UART1_BASE   /*0X02020000*/
    
    /* MMC Configs */
    #ifdef CONFIG_FSL_USDHC
    #define CONFIG_SYS_FSL_ESDHC_ADDR	USDHC2_BASE_ADDR  /*EMMC接在USDHC2上,这个是EMMC所使用接口的寄存器基地址*/
    
    /* NAND pin conflicts with usdhc2 */  /*NAND跟USDHC2的引脚冲突,使用NAND只能使用一个USDHC设备 SD卡,没有NAND就有SD卡以及EMMC*/
    #ifdef CONFIG_SYS_USE_NAND
    #define CONFIG_SYS_FSL_USDHC_NUM	1
    #else
    #define CONFIG_SYS_FSL_USDHC_NUM	2
    #endif
    #endif
    
    /* I2C configs */
    #define CONFIG_CMD_I2C
    #ifdef CONFIG_CMD_I2C
    #define CONFIG_SYS_I2C
    #define CONFIG_SYS_I2C_MXC
    #define CONFIG_SYS_I2C_MXC_I2C1		/* enable I2C bus 1 */
    #define CONFIG_SYS_I2C_MXC_I2C2		/* enable I2C bus 2 */
    #define CONFIG_SYS_I2C_SPEED		100000
    
    /* PMIC only for 9X9 EVK */
    #define CONFIG_POWER
    #define CONFIG_POWER_I2C
    #define CONFIG_POWER_PFUZE3000
    #define CONFIG_POWER_PFUZE3000_I2C_ADDR  0x08
    #endif
    
    #define CONFIG_SYS_MMC_IMG_LOAD_PART	1
    
    #ifdef CONFIG_SYS_BOOT_NAND
    #define CONFIG_MFG_NAND_PARTITION "mtdparts=gpmi-nand:64m(boot),16m(kernel),16m(dtb),1m(misc),-(rootfs) "
    #else
    #define CONFIG_MFG_NAND_PARTITION ""
    #endif
    
    /*使用MfgTool烧写系统时候会用到这里面的环境变量*/
    #define CONFIG_MFG_ENV_SETTINGS \
    	"mfgtool_args=setenv bootargs console=${console},${baudrate} " \
    	    CONFIG_BOOTARGS_CMA_SIZE \
    		"rdinit=/linuxrc " \
    		"g_mass_storage.stall=0 g_mass_storage.removable=1 " \
    		"g_mass_storage.file=/fat g_mass_storage.ro=1 " \
    		"g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\
    		"g_mass_storage.iSerialNumber=\"\" "\
    		CONFIG_MFG_NAND_PARTITION \
    		"clk_ignore_unused "\
    		"\0" \
    	"initrd_addr=0x83800000\0" \
    	"initrd_high=0xffffffff\0" \
    	"bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \
    /* 设置宏 CONFIG_EXTRA_ENV_SETTINGS 设置一些环境变量的参数*/
    #if defined(CONFIG_SYS_BOOT_NAND)
    #define CONFIG_EXTRA_ENV_SETTINGS \
    	CONFIG_MFG_ENV_SETTINGS \
    	"panel=ATK-LCD-4.3-800X480\0" \
    	"fdt_addr=0x83000000\0" \
    	"fdt_high=0xffffffff\0"	  \
    	"console=ttymxc0\0" \
    	"bootargs=console=ttymxc0,115200 ubi.mtd=4 "  \
    		"root=ubi0:rootfs rootfstype=ubifs "		     \
    		CONFIG_BOOTARGS_CMA_SIZE \
    		"mtdparts=gpmi-nand:64m(boot),16m(kernel),16m(dtb),1m(misc),-(rootfs)\0"\
    	"bootcmd=nand read ${loadaddr} 0x4000000 0x800000;"\
    		"nand read ${fdt_addr} 0x5000000 0x100000;"\
    		"bootz ${loadaddr} - ${fdt_addr}\0"
    
    #else
    #define CONFIG_EXTRA_ENV_SETTINGS \
    	CONFIG_MFG_ENV_SETTINGS \
    	"script=boot.scr\0" \
    	"image=zImage\0" \
    	"console=ttymxc0\0" \
    	"fdt_high=0xffffffff\0" \
    	"initrd_high=0xffffffff\0" \
    	"fdt_file=undefined\0" \
    	"fdt_addr=0x83000000\0" \
    	"boot_fdt=try\0" \
    	"ip_dyn=yes\0" \
    	"panel=ATK-LCD-4.3-800X480\0" \
    	"mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \
    	"mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
    	"mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
    	"mmcautodetect=yes\0" \
    	"mmcargs=setenv bootargs console=${console},${baudrate} " \
    		CONFIG_BOOTARGS_CMA_SIZE \
    		"root=${mmcroot}\0" \
    	"loadbootscript=" \
    		"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
    	"bootscript=echo Running bootscript from mmc ...; " \
    		"source\0" \
    	"loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
    	"loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
    	"mmcboot=echo Booting from mmc ...; " \
    		"run mmcargs; " \
    		"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
    			"if run loadfdt; then " \
    				"bootz ${loadaddr} - ${fdt_addr}; " \
    			"else " \
    				"if test ${boot_fdt} = try; then " \
    					"bootz; " \
    				"else " \
    					"echo WARN: Cannot load the DT; " \
    				"fi; " \
    			"fi; " \
    		"else " \
    			"bootz; " \
    		"fi;\0" \
    	"netargs=setenv bootargs console=${console},${baudrate} " \
    		CONFIG_BOOTARGS_CMA_SIZE \
    		"root=/dev/nfs " \
    	"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
    		"netboot=echo Booting from net ...; " \
    		"run netargs; " \
    		"if test ${ip_dyn} = yes; then " \
    			"setenv get_cmd dhcp; " \
    		"else " \
    			"setenv get_cmd tftp; " \
    		"fi; " \
    		"${get_cmd} ${image}; " \
    		"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
    			"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
    				"bootz ${loadaddr} - ${fdt_addr}; " \
    			"else " \
    				"if test ${boot_fdt} = try; then " \
    					"bootz; " \
    				"else " \
    					"echo WARN: Cannot load the DT; " \
    				"fi; " \
    			"fi; " \
    		"else " \
    			"bootz; " \
    		"fi;\0" \
    		"findfdt="\
    			"if test $fdt_file = undefined; then " \
    				"if test $board_name = EVK && test $board_rev = 9X9; then " \
    					"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \
    				"if test $board_name = EVK && test $board_rev = 14X14; then " \
    					"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
    				"if test $fdt_file = undefined; then " \
    					"echo WARNING: Could not determine dtb to use; fi; " \
    			"fi;\0" \
    /* CONFIG_BOOTCOMMAND 设置环境变量bootcmd的值*/
    /*
    #define CONFIG_BOOTCOMMAND \
    	   "run findfdt;" \
    	   "mmc dev ${mmcdev};" \
    	   "mmc dev ${mmcdev}; if mmc rescan; then " \
    		   "if run loadbootscript; then " \
    			   "run bootscript; " \
    		   "else " \
    			   "if run loadimage; then " \
    				   "run mmcboot; " \
    			   "else run netboot; " \
    			   "fi; " \
    		   "fi; " \
    	   "else run netboot; fi"
    #endif
    */
    #define CONFIG_BOOTCOMMAND \ 
        "mmc dev 1;" \ 
        "fatload mmc 1:1 0x80800000 zImage;" \ 
        "fatload mmc 1:1 0x83000000 imx6ull-alientek-emmc.dtb;" \ 
        "bootz 0x80800000 - 0x83000000;" 
    
    /* Miscellaneous configurable options */
    #define CONFIG_CMD_MEMTEST          /*设置memset相关的宏定义,比如使能memtest,设置测试的内存起始地址以及内存大小*/
    #define CONFIG_SYS_MEMTEST_START	0x80000000
    #define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x8000000)
    
    #define CONFIG_SYS_LOAD_ADDR		CONFIG_LOADADDR  /*linux kernel在DRAM中的装载地址*/  /* CONFIG_LOADADDR是Linux kernel的存储首地址是0X8080000*/
    #define CONFIG_SYS_HZ			1000    /*系统时钟频率是1000Hz*/
    #define CONFIG_STACKSIZE		SZ_128K /*CONFIG_STACKSIZE为栈大小,这里为128KB*/
    
    /* Physical Memory Map */
    #define CONFIG_NR_DRAM_BANKS		1   /*DRAM BANK的数目,只有一块DRAM BANK*/
    #define PHYS_SDRAM			MMDC0_ARB_BASE_ADDR /*DRAM控制器MMDC0所管辖的DRAM范围的起始地址,也就是0X80000000*/
    
    #define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM      /*DRAM的起始地址*/
    #define CONFIG_SYS_INIT_RAM_ADDR	IRAM_BASE_ADDR  /*I.MX6ULL内部的IRAM的起始地址,也就是OCRA的起始地址,为0X00900000S*/
    #define CONFIG_SYS_INIT_RAM_SIZE	IRAM_SIZE       /*IRAM(OCRAM)的大小,为128KB*/
    
    #define CONFIG_SYS_INIT_SP_OFFSET \
    	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)   /*初始sp偏移*/
    #define CONFIG_SYS_INIT_SP_ADDR \
    	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) /*初始sp地址*/
    
    /* FLASH and environment organization */
    #define CONFIG_SYS_NO_FLASH
    
    #ifdef CONFIG_SYS_BOOT_QSPI
    #define CONFIG_FSL_QSPI
    #define CONFIG_ENV_IS_IN_SPI_FLASH
    #elif defined CONFIG_SYS_BOOT_NAND
    #define CONFIG_SYS_USE_NAND
    #define CONFIG_ENV_IS_IN_NAND
    #else
    #define CONFIG_FSL_QSPI
    #define CONFIG_ENV_IS_IN_MMC
    #endif
    
    #define CONFIG_SYS_MMC_ENV_DEV		1   /* USDHC2 */   /*默认的MMC设备为USDHC2,也就是EMMC*/
    #define CONFIG_SYS_MMC_ENV_PART		0	/* user area */ /*模式分区,默认为第0个分区*/
    #define CONFIG_MMCROOT			"/dev/mmcblk1p2"  /* USDHC2 */ /*根文件系统为EMMC的第2个分区。第0个分区是uboot,第一个分区是linux镜像和设备树,第二个分区时Linux的根文件系统*/
    
    #define CONFIG_CMD_BMODE
    
    #ifdef CONFIG_FSL_QSPI
    #define CONFIG_QSPI_BASE		QSPI0_BASE_ADDR
    #define CONFIG_QSPI_MEMMAP_BASE		QSPI0_AMBA_BASE
    
    #define CONFIG_CMD_SF
    #define CONFIG_SPI_FLASH
    #define CONFIG_SPI_FLASH_BAR
    #define CONFIG_SF_DEFAULT_BUS		0
    #define CONFIG_SF_DEFAULT_CS		0
    #define CONFIG_SF_DEFAULT_SPEED	40000000
    #define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
    #define CONFIG_SPI_FLASH_STMICRO
    #endif
    
    /* NAND stuff */
    #ifdef CONFIG_SYS_USE_NAND
    #define CONFIG_CMD_NAND
    #define CONFIG_CMD_NAND_TRIMFFS
    
    #define CONFIG_NAND_MXS
    #define CONFIG_SYS_MAX_NAND_DEVICE	1
    #define CONFIG_SYS_NAND_BASE		0x40000000
    #define CONFIG_SYS_NAND_5_ADDR_CYCLE
    #define CONFIG_SYS_NAND_ONFI_DETECTION
    
    /* DMA stuff, needed for GPMI/MXS NAND support */
    #define CONFIG_APBH_DMA
    #define CONFIG_APBH_DMA_BURST
    #define CONFIG_APBH_DMA_BURST8
    #endif
    
    #define CONFIG_ENV_SIZE			SZ_8K               /*环境变量大小,默认为8KB*/
    #if defined(CONFIG_ENV_IS_IN_MMC)
    #define CONFIG_ENV_OFFSET		(12 * SZ_64K)       /*环境变量保存EMMC中,环境变量偏移地址12*64KB*/
    #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
    #define CONFIG_ENV_OFFSET		(768 * 1024)        /*环境变量保存SPI FLASH中,环境变量偏移地址768*1024*/
    #define CONFIG_ENV_SECT_SIZE		(64 * 1024)
    #define CONFIG_ENV_SPI_BUS		CONFIG_SF_DEFAULT_BUS
    #define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS
    #define CONFIG_ENV_SPI_MODE		CONFIG_SF_DEFAULT_MODE
    #define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED
    #elif defined(CONFIG_ENV_IS_IN_NAND)
    #undef CONFIG_ENV_SIZE
    #define CONFIG_ENV_OFFSET		(60 << 20)          /*环境变量保存NAND中,环境变量偏移地址为60<<20(60MB),重新设置环境变量的大小为128KB*/
    #define CONFIG_ENV_SECT_SIZE		(128 << 10)
    #define CONFIG_ENV_SIZE			CONFIG_ENV_SECT_SIZE
    #endif
    
    
    /* USB Configs */
    #define CONFIG_CMD_USB
    #ifdef CONFIG_CMD_USB
    #define CONFIG_USB_EHCI
    #define CONFIG_USB_EHCI_MX6
    #define CONFIG_USB_STORAGE
    #define CONFIG_EHCI_HCD_INIT_AFTER_RESET
    #define CONFIG_USB_HOST_ETHER
    #define CONFIG_USB_ETHER_ASIX
    #define CONFIG_MXC_USB_PORTSC  (PORT_PTS_UTMI | PORT_PTS_PTW)
    #define CONFIG_MXC_USB_FLAGS   0
    #define CONFIG_USB_MAX_CONTROLLER_COUNT 2
    #endif
    
    #ifdef CONFIG_CMD_NET       /*使能网络的dhcp以及ping命令等*/
    #define CONFIG_CMD_PING
    #define CONFIG_CMD_DHCP
    #define CONFIG_CMD_MII
    #define CONFIG_FEC_MXC
    #define CONFIG_MII
    #define CONFIG_FEC_ENET_DEV		1  
    /*指定所使用的网口,为0的时候使用ENET1,为1的时候使用ENTT2*/
    
    #if (CONFIG_FEC_ENET_DEV == 0)
    #define IMX_FEC_BASE			ENET_BASE_ADDR    /*ENET接口的寄存器首地址*/
    #define CONFIG_FEC_MXC_PHYADDR          0x2       /*网口PHY芯片的地址*/
    #define CONFIG_FEC_XCV_TYPE             RMII      /*PHY芯片所使用的接口类型,使用的时RMII接口*/
    #elif (CONFIG_FEC_ENET_DEV == 1)
    #define IMX_FEC_BASE			ENET2_BASE_ADDR
    #define CONFIG_FEC_MXC_PHYADDR		0x1
    #define CONFIG_FEC_XCV_TYPE		RMII
    #endif
    #define CONFIG_ETHPRIME			"FEC"
    
    #define CONFIG_PHYLIB
    #define CONFIG_PHY_REALTK
    #endif
    
    #define CONFIG_IMX_THERMAL
    
    #ifndef CONFIG_SPL_BUILD
    #define CONFIG_VIDEO            /*开启LCD*/
    #ifdef CONFIG_VIDEO
    #define CONFIG_CFB_CONSOLE
    #define CONFIG_VIDEO_MXS
    #define CONFIG_VIDEO_LOGO      /*使能Logo显示*/
    #define CONFIG_VIDEO_SW_CURSOR
    #define CONFIG_VGA_AS_SINGLE_DEVICE
    #define CONFIG_SYS_CONSOLE_IS_IN_ENV
    #define CONFIG_SPLASH_SCREEN
    #define CONFIG_SPLASH_SCREEN_ALIGN
    #define CONFIG_CMD_BMP         /*使能BMP图片显示指令*/
    #define CONFIG_BMP_16BPP
    #define CONFIG_VIDEO_BMP_RLE8
    #define CONFIG_VIDEO_BMP_LOGO
    #define CONFIG_IMX_VIDEO_SKIP
    #endif
    #endif
    
    #define CONFIG_IOMUX_LPSR
    
    #if defined(CONFIG_ANDROID_SUPPORT)
    #include "mx6ullevk_android.h"
    #endif
    
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    1.5.12 mx6ull_alientek_emmc.c
    /*
     * Copyright (C) 2016 Freescale Semiconductor, Inc.
     *
     * SPDX-License-Identifier:	GPL-2.0+
     */
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include "../common/pfuze.h"
    #include 
    #include 
    #include 
    
    #ifdef CONFIG_FSL_FASTBOOT
    #include 
    #ifdef CONFIG_ANDROID_RECOVERY
    #include 
    #endif
    #endif /*CONFIG_FSL_FASTBOOT*/
    
    DECLARE_GLOBAL_DATA_PTR;
    
    #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
    	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
    	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
    
    #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
    	PAD_CTL_PUS_22K_UP  | PAD_CTL_SPEED_LOW |		\
    	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
    
    #define USDHC_DAT3_CD_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |	\
    	PAD_CTL_PUS_100K_DOWN  | PAD_CTL_SPEED_LOW |		\
    	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
    
    #define I2C_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_PUE |            \
    	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
    	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
    	PAD_CTL_ODE)
    
    #define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
    	PAD_CTL_SPEED_HIGH   |                                  \
    	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST)
    
    #define LCD_PAD_CTRL    (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
    	PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
    
    #define MDIO_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_PUE |     \
    	PAD_CTL_DSE_48ohm   | PAD_CTL_SRE_FAST | PAD_CTL_ODE)
    
    #define ENET_CLK_PAD_CTRL  (PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
    
    #define ENET_RX_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |          \
    	PAD_CTL_SPEED_HIGH   | PAD_CTL_SRE_FAST)
    
    #define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
    #define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
    			PAD_CTL_SRE_FAST)
    #define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
    
    #define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
    		PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
    		PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST)
    
    #define SPI_PAD_CTRL (PAD_CTL_HYS |				\
    	PAD_CTL_SPEED_MED |		\
    	PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
    
    #define OTG_ID_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
    	PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |		\
    	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
    
    /* #define IOX_SDI IMX_GPIO_NR(5, 10)     74LV595芯片注释
       #define IOX_STCP IMX_GPIO_NR(5, 7)
       #define IOX_SHCP IMX_GPIO_NR(5, 11)   
       #define IOX_OE IMX_GPIO_NR(5, 8)
    */
    #define ENET1_RESET   IMX_GPIO_NR(5,7)    /* ENET1的复位引脚连接到 SNVS_TAMPER7上,对应 GPIO5_IO07 */
    #define ENET2_RESET   IMX_GPIO_NR(5,8)    /* ENET2的复位引脚连接到 SNVS_TAMPER8上,对应 GPIO5_IO08 */
    
    
    /*
     * HDMI_nRST --> Q0
     * ENET1_nRST --> Q1
     * ENET2_nRST --> Q2
     * CAN1_2_STBY --> Q3
     * BT_nPWD --> Q4
     * CSI_RST --> Q5
     * CSI_PWDN --> Q6
     * LCD_nPWREN --> Q7
     */
    enum qn {
    	HDMI_NRST,
    	ENET1_NRST,
    	ENET2_NRST,
    	CAN1_2_STBY,
    	BT_NPWD,
    	CSI_RST,
    	CSI_PWDN,
    	LCD_NPWREN,
    };
    
    enum qn_func {
    	qn_reset,
    	qn_enable,
    	qn_disable,
    };
    
    enum qn_level {
    	qn_low = 0,
    	qn_high = 1,
    };
    
    static enum qn_level seq[3][2] = {
    	{0, 1}, {1, 1}, {0, 0}
    };
    
    static enum qn_func qn_output[8] = {
    	qn_reset, qn_reset, qn_reset, qn_enable, qn_disable, qn_reset,
    	qn_disable, qn_disable
    };
    
    #ifdef CONFIG_SYS_I2C_MXC
    #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
    /* I2C1 for PMIC and EEPROM */
    static struct i2c_pads_info i2c_pad_info1 = {
    	.scl = {
    		.i2c_mode =  MX6_PAD_UART4_TX_DATA__I2C1_SCL | PC,
    		.gpio_mode = MX6_PAD_UART4_TX_DATA__GPIO1_IO28 | PC,
    		.gp = IMX_GPIO_NR(1, 28),
    	},
    	.sda = {
    		.i2c_mode = MX6_PAD_UART4_RX_DATA__I2C1_SDA | PC,
    		.gpio_mode = MX6_PAD_UART4_RX_DATA__GPIO1_IO29 | PC,
    		.gp = IMX_GPIO_NR(1, 29),
    	},
    };
    
    #ifdef CONFIG_POWER
    #define I2C_PMIC       0
    int power_init_board(void)
    {
    	if (is_mx6ull_9x9_evk()) {
    		struct pmic *pfuze;
    		int ret;
    		unsigned int reg, rev_id;
    
    		ret = power_pfuze3000_init(I2C_PMIC);
    		if (ret)
    			return ret;
    
    		pfuze = pmic_get("PFUZE3000");
    		ret = pmic_probe(pfuze);
    		if (ret)
    			return ret;
    
    		pmic_reg_read(pfuze, PFUZE3000_DEVICEID, ®);
    		pmic_reg_read(pfuze, PFUZE3000_REVID, &rev_id);
    		printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n",
    		       reg, rev_id);
    
    		/* disable Low Power Mode during standby mode */
    		pmic_reg_read(pfuze, PFUZE3000_LDOGCTL, ®);
    		reg |= 0x1;
    		pmic_reg_write(pfuze, PFUZE3000_LDOGCTL, reg);
    
    		/* SW1B step ramp up time from 2us to 4us/25mV */
    		reg = 0x40;
    		pmic_reg_write(pfuze, PFUZE3000_SW1BCONF, reg);
    
    		/* SW1B mode to APS/PFM */
    		reg = 0xc;
    		pmic_reg_write(pfuze, PFUZE3000_SW1BMODE, reg);
    
    		/* SW1B standby voltage set to 0.975V */
    		reg = 0xb;
    		pmic_reg_write(pfuze, PFUZE3000_SW1BSTBY, reg);
    	}
    
    	return 0;
    }
    
    #ifdef CONFIG_LDO_BYPASS_CHECK
    void ldo_mode_set(int ldo_bypass)
    {
    	unsigned int value;
    	u32 vddarm;
    
    	struct pmic *p = pmic_get("PFUZE3000");
    
    	if (!p) {
    		printf("No PMIC found!\n");
    		return;
    	}
    
    	/* switch to ldo_bypass mode */
    	if (ldo_bypass) {
    		prep_anatop_bypass();
    		/* decrease VDDARM to 1.275V */
    		pmic_reg_read(p, PFUZE3000_SW1BVOLT, &value);
    		value &= ~0x1f;
    		value |= PFUZE3000_SW1AB_SETP(1275);
    		pmic_reg_write(p, PFUZE3000_SW1BVOLT, value);
    
    		set_anatop_bypass(1);
    		vddarm = PFUZE3000_SW1AB_SETP(1175);
    
    		pmic_reg_read(p, PFUZE3000_SW1BVOLT, &value);
    		value &= ~0x1f;
    		value |= vddarm;
    		pmic_reg_write(p, PFUZE3000_SW1BVOLT, value);
    
    		finish_anatop_bypass();
    
    		printf("switch to ldo_bypass mode!\n");
    	}
    }
    #endif
    #endif
    #endif
    
    int dram_init(void)
    {
    	gd->ram_size = imx_ddr_size();
    
    	return 0;
    }
    
    static iomux_v3_cfg_t const uart1_pads[] = {
    	MX6_PAD_UART1_TX_DATA__UART1_DCE_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
    	MX6_PAD_UART1_RX_DATA__UART1_DCE_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
    };
    
    static iomux_v3_cfg_t const usdhc1_pads[] = {
    	MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    
    	/* VSELECT */
    	MX6_PAD_GPIO1_IO05__USDHC1_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	/* CD */
    	MX6_PAD_UART1_RTS_B__GPIO1_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
    	/* RST_B */
    	MX6_PAD_GPIO1_IO09__GPIO1_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
    };
    
    /*
     * mx6ull_14x14_evk board default supports sd card. If want to use
     * EMMC, need to do board rework for sd2.
     * Introduce CONFIG_MX6ULL_EVK_EMMC_REWORK, if sd2 reworked to support
     * emmc, need to define this macro.
     */
    #if defined(CONFIG_MX6ULL_EVK_EMMC_REWORK)
    static iomux_v3_cfg_t const usdhc2_emmc_pads[] = {
    	MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA04__USDHC2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA05__USDHC2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA06__USDHC2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA07__USDHC2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    
    	/*
    	 * RST_B
    	 */
    	MX6_PAD_NAND_ALE__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
    };
    #else
    static iomux_v3_cfg_t const usdhc2_pads[] = {
    	MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    	MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
    };
    
    static iomux_v3_cfg_t const usdhc2_cd_pads[] = {
    	/*
    	 * The evk board uses DAT3 to detect CD card plugin,
    	 * in u-boot we mux the pin to GPIO when doing board_mmc_getcd.
    	 */
    	MX6_PAD_NAND_DATA03__GPIO4_IO05 | MUX_PAD_CTRL(USDHC_DAT3_CD_PAD_CTRL),
    };
    
    static iomux_v3_cfg_t const usdhc2_dat3_pads[] = {
    	MX6_PAD_NAND_DATA03__USDHC2_DATA3 |
    	MUX_PAD_CTRL(USDHC_DAT3_CD_PAD_CTRL),
    };
    #endif
    
    static void setup_iomux_uart(void)
    {
    	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
    }
    
    #ifdef CONFIG_FSL_QSPI
    
    #define QSPI_PAD_CTRL1	\
    	(PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
    	 PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_120ohm)
    
    static iomux_v3_cfg_t const quadspi_pads[] = {
    	MX6_PAD_NAND_WP_B__QSPI_A_SCLK | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    	MX6_PAD_NAND_READY_B__QSPI_A_DATA00 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    	MX6_PAD_NAND_CE0_B__QSPI_A_DATA01 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    	MX6_PAD_NAND_CE1_B__QSPI_A_DATA02 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    	MX6_PAD_NAND_CLE__QSPI_A_DATA03 | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    	MX6_PAD_NAND_DQS__QSPI_A_SS0_B | MUX_PAD_CTRL(QSPI_PAD_CTRL1),
    };
    
    static int board_qspi_init(void)
    {
    	/* Set the iomux */
    	imx_iomux_v3_setup_multiple_pads(quadspi_pads,
    					 ARRAY_SIZE(quadspi_pads));
    	/* Set the clock */
    	enable_qspi_clk(0);
    
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_FSL_ESDHC
    static struct fsl_esdhc_cfg usdhc_cfg[2] = {
    	{USDHC1_BASE_ADDR, 0, 4},
    #if defined(CONFIG_MX6ULL_EVK_EMMC_REWORK)
    	{USDHC2_BASE_ADDR, 0, 8},
    #else
    	{USDHC2_BASE_ADDR, 0, 4},
    #endif
    };
    
    #define USDHC1_CD_GPIO	IMX_GPIO_NR(1, 19)
    #define USDHC1_PWR_GPIO	IMX_GPIO_NR(1, 9)
    #define USDHC2_CD_GPIO	IMX_GPIO_NR(4, 5)
    #define USDHC2_PWR_GPIO	IMX_GPIO_NR(4, 10)
    
    int board_mmc_get_env_dev(int devno)
    {
    	if (devno == 1 && mx6_esdhc_fused(USDHC1_BASE_ADDR))
    		devno = 0;
    
    	return devno;
    }
    
    int mmc_map_to_kernel_blk(int devno)
    {
    	if (devno == 0 && mx6_esdhc_fused(USDHC1_BASE_ADDR))
    		devno = 1;
    
    	return devno;
    }
    
    int board_mmc_getcd(struct mmc *mmc)
    {
    	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
    	int ret = 0;
    
    	switch (cfg->esdhc_base) {
    	case USDHC1_BASE_ADDR:
    		ret = !gpio_get_value(USDHC1_CD_GPIO);
    		break;
    	case USDHC2_BASE_ADDR:
    #if defined(CONFIG_MX6ULL_EVK_EMMC_REWORK)
    		ret = 1;
    #else
    		imx_iomux_v3_setup_multiple_pads(usdhc2_cd_pads,
    						 ARRAY_SIZE(usdhc2_cd_pads));
    		gpio_direction_input(USDHC2_CD_GPIO);
    
    		/*
    		 * Since it is the DAT3 pin, this pin is pulled to
    		 * low voltage if no card
    		 */
    		ret = gpio_get_value(USDHC2_CD_GPIO);
    
    		imx_iomux_v3_setup_multiple_pads(usdhc2_dat3_pads,
    						 ARRAY_SIZE(usdhc2_dat3_pads));
    #endif
    		break;
    	}
    
    	return ret;
    }
    
    int board_mmc_init(bd_t *bis)
    {
    #ifdef CONFIG_SPL_BUILD
    #if defined(CONFIG_MX6ULL_EVK_EMMC_REWORK)
    	imx_iomux_v3_setup_multiple_pads(usdhc2_emmc_pads,
    					 ARRAY_SIZE(usdhc2_emmc_pads));
    #else
    	imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
    #endif
    	gpio_direction_output(USDHC2_PWR_GPIO, 0);
    	udelay(500);
    	gpio_direction_output(USDHC2_PWR_GPIO, 1);
    	usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
    	return fsl_esdhc_initialize(bis, &usdhc_cfg[1]);
    #else
    	int i, ret;
    
    	/*
    	 * According to the board_mmc_init() the following map is done:
    	 * (U-Boot device node)    (Physical Port)
    	 * mmc0                    USDHC1
    	 * mmc1                    USDHC2
    	 */
    	for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
    		switch (i) {
    		case 0:
    			imx_iomux_v3_setup_multiple_pads(
    				usdhc1_pads, ARRAY_SIZE(usdhc1_pads));
    			gpio_direction_input(USDHC1_CD_GPIO);
    			usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
    
    			gpio_direction_output(USDHC1_PWR_GPIO, 0);
    			udelay(500);
    			gpio_direction_output(USDHC1_PWR_GPIO, 1);
    			break;
    		case 1:
    #if defined(CONFIG_MX6ULL_EVK_EMMC_REWORK)
    			imx_iomux_v3_setup_multiple_pads(
    				usdhc2_emmc_pads, ARRAY_SIZE(usdhc2_emmc_pads));
    #else
    #ifndef CONFIG_SYS_USE_NAND
    			imx_iomux_v3_setup_multiple_pads(
    				usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
    #endif
    #endif
    			gpio_direction_output(USDHC2_PWR_GPIO, 0);
    			udelay(500);
    			gpio_direction_output(USDHC2_PWR_GPIO, 1);
    			usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
    			break;
    		default:
    			printf("Warning: you configured more USDHC controllers (%d) than supported by the board\n", i + 1);
    			return -EINVAL;
    			}
    
    			ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
    			if (ret) {
    				printf("Warning: failed to initialize mmc dev %d\n", i);
    			}
    	}
    #endif
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_USB_EHCI_MX6
    #define USB_OTHERREGS_OFFSET	0x800
    #define UCTRL_PWR_POL		(1 << 9)
    
    static iomux_v3_cfg_t const usb_otg_pads[] = {
    	MX6_PAD_GPIO1_IO00__ANATOP_OTG1_ID | MUX_PAD_CTRL(OTG_ID_PAD_CTRL),
    };
    
    /* At default the 3v3 enables the MIC2026 for VBUS power */
    static void setup_usb(void)
    {
    	imx_iomux_v3_setup_multiple_pads(usb_otg_pads,
    					 ARRAY_SIZE(usb_otg_pads));
    }
    
    int board_usb_phy_mode(int port)
    {
    	if (port == 1)
    		return USB_INIT_HOST;
    	else
    		return usb_phy_mode(port);
    }
    
    int board_ehci_hcd_init(int port)
    {
    	u32 *usbnc_usb_ctrl;
    
    	if (port > 1)
    		return -EINVAL;
    
    	usbnc_usb_ctrl = (u32 *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET +
    				 port * 4);
    
    	/* Set Power polarity */
    	setbits_le32(usbnc_usb_ctrl, UCTRL_PWR_POL);
    
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_NAND_MXS
    static iomux_v3_cfg_t const nand_pads[] = {
    	MX6_PAD_NAND_DATA00__RAWNAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA01__RAWNAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA02__RAWNAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA03__RAWNAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA04__RAWNAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA05__RAWNAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA06__RAWNAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DATA07__RAWNAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_CLE__RAWNAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_ALE__RAWNAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_CE0_B__RAWNAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_CE1_B__RAWNAND_CE1_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_RE_B__RAWNAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_WE_B__RAWNAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_WP_B__RAWNAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_READY_B__RAWNAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    	MX6_PAD_NAND_DQS__RAWNAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL2),
    };
    
    static void setup_gpmi_nand(void)
    {
    	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
    
    	/* config gpmi nand iomux */
    	imx_iomux_v3_setup_multiple_pads(nand_pads, ARRAY_SIZE(nand_pads));
    
    	setup_gpmi_io_clk((3 << MXC_CCM_CSCDR1_BCH_PODF_OFFSET) |
    			  (3 << MXC_CCM_CSCDR1_GPMI_PODF_OFFSET));
    
    	/* enable apbh clock gating */
    	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
    }
    #endif
    
    #ifdef CONFIG_FEC_MXC
    /*
     * pin conflicts for fec1 and fec2, GPIO1_IO06 and GPIO1_IO07 can only
     * be used for ENET1 or ENET2, cannot be used for both.
     */
    static iomux_v3_cfg_t const fec1_pads[] = {
    	MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
    	MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
    	MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), 
    };
    
    static iomux_v3_cfg_t const fec2_pads[] = {
    	MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
    	MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
    
    	MX6_PAD_ENET2_TX_DATA0__ENET2_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET2_TX_DATA1__ENET2_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL),
    	MX6_PAD_ENET2_TX_EN__ENET2_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    
    	MX6_PAD_ENET2_RX_DATA0__ENET2_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET2_RX_DATA1__ENET2_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
    	MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
    };
    
    static void setup_iomux_fec(int fec_id) 
    { 
        if (fec_id == 0) 
        { 
     
            imx_iomux_v3_setup_multiple_pads(fec1_pads, 
                             ARRAY_SIZE(fec1_pads)); 
     
            gpio_direction_output(ENET1_RESET, 1); 
            gpio_set_value(ENET1_RESET, 0); 
            mdelay(20); 
            gpio_set_value(ENET1_RESET, 1); 
        } 
        else 
        { 
            imx_iomux_v3_setup_multiple_pads(fec2_pads, 
                             ARRAY_SIZE(fec2_pads)); 
            gpio_direction_output(ENET2_RESET, 1); 
            gpio_set_value(ENET2_RESET, 0); 
            mdelay(20); 
            gpio_set_value(ENET2_RESET, 1); 
        } 
       mdelay(150); /* 复位结束后至少延时 150ms才能正常使用*/ 
    } 
    
    int board_eth_init(bd_t *bis)
    {
    	setup_iomux_fec(CONFIG_FEC_ENET_DEV);
    
    	return fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV,
    				       CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
    }
    
    static int setup_fec(int fec_id)
    {
    	struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
    	int ret;
    
    	if (fec_id == 0) {
    		/*
    		 * Use 50M anatop loopback REF_CLK1 for ENET1,
    		 * clear gpr1[13], set gpr1[17].
    		 */
    		clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK,
    				IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK);
    	} else {
    		/*
    		 * Use 50M anatop loopback REF_CLK2 for ENET2,
    		 * clear gpr1[14], set gpr1[18].
    		 */
    		clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC2_MASK,
    				IOMUX_GPR1_FEC2_CLOCK_MUX1_SEL_MASK);
    	}
    
    	ret = enable_fec_anatop_clock(fec_id, ENET_50MHZ);
    	if (ret)
    		return ret;
    
    	enable_enet_clk(1);
    
    	return 0;
    }
    
    int board_phy_config(struct phy_device *phydev)
    {
    	phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190);
    
    	if (phydev->drv->config)
    		phydev->drv->config(phydev);
    
    	return 0;
    }
    #endif
    
    #ifdef CONFIG_VIDEO_MXS
    static iomux_v3_cfg_t const lcd_pads[] = {
    	MX6_PAD_LCD_CLK__LCDIF_CLK | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_ENABLE__LCDIF_ENABLE | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_HSYNC__LCDIF_HSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_VSYNC__LCDIF_VSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA00__LCDIF_DATA00 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA01__LCDIF_DATA01 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA02__LCDIF_DATA02 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA03__LCDIF_DATA03 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA04__LCDIF_DATA04 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA05__LCDIF_DATA05 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA06__LCDIF_DATA06 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA07__LCDIF_DATA07 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA08__LCDIF_DATA08 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA09__LCDIF_DATA09 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA10__LCDIF_DATA10 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA11__LCDIF_DATA11 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA12__LCDIF_DATA12 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA13__LCDIF_DATA13 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA14__LCDIF_DATA14 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA15__LCDIF_DATA15 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA16__LCDIF_DATA16 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA17__LCDIF_DATA17 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA18__LCDIF_DATA18 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA19__LCDIF_DATA19 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA20__LCDIF_DATA20 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA21__LCDIF_DATA21 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA22__LCDIF_DATA22 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    	MX6_PAD_LCD_DATA23__LCDIF_DATA23 | MUX_PAD_CTRL(LCD_PAD_CTRL),
    
    	/* LCD_RST */
    	MX6_PAD_SNVS_TAMPER9__GPIO5_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
    
    	/* Use GPIO for Brightness adjustment, duty cycle = period. */
    	MX6_PAD_GPIO1_IO08__GPIO1_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
    };
    
    void do_enable_parallel_lcd(struct display_info_t const *dev)
    {
    	enable_lcdif_clock(dev->bus);
    
    	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));
    
    	/* Reset the LCD */
    	gpio_direction_output(IMX_GPIO_NR(5, 9) , 0);
    	udelay(500);
    	gpio_direction_output(IMX_GPIO_NR(5, 9) , 1);
    
    	/* Set Brightness to high */
    	gpio_direction_output(IMX_GPIO_NR(1, 8) , 1);
    }
    
    struct display_info_t const displays[] = {{
    	.bus = MX6UL_LCDIF1_BASE_ADDR, 
    	.addr = 0,
    	.pixfmt = 24,    /* RGB888,此时就是24位 */
    	.detect = NULL,
    	.enable	= do_enable_parallel_lcd,
    	.mode	= {
    		.name		   = "ATK-LCD-4.3-800X480",    /* LCD名字 */
    		.xres           = 800,           /* x轴像素数量 */
    		.yres           = 480,			/* Y轴像素数量 */
    		.pixclock       = 10119,         /* 每个像素时钟的时钟周期长度,为ps*/
    		.left_margin    = 210,           /* HBP 水平同步后肩*/
    		.right_margin   = 46,			/* HFP 水平同步前肩*/
    		.upper_margin   = 22,			/* VBP 垂直同步后肩*/
    		.lower_margin   = 23,			/* VFP 垂直同步后肩*/
    		.hsync_len      = 20,			/* HSPW 行同步脉宽*/
    		.vsync_len      = 3,			/* VSPW 垂直同步脉宽*/
    		.sync           = 0,			
    		.vmode          = FB_VMODE_NONINTERLACED   /* 不使用隔行扫描 */
    } } };
    size_t display_count = ARRAY_SIZE(displays);
    #endif
    
    int board_early_init_f(void)
    {
    	setup_iomux_uart();
    
    	return 0;
    }
    
    int board_init(void)
    {
    	/* Address of boot parameters */
    	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
    
    	imx_iomux_v3_setup_multiple_pads(iox_pads, ARRAY_SIZE(iox_pads));
    
    	iox74lv_init();
    
    #ifdef CONFIG_SYS_I2C_MXC
    	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
    #endif
    
    #ifdef	CONFIG_FEC_MXC
    	setup_fec(CONFIG_FEC_ENET_DEV);
    #endif
    
    #ifdef CONFIG_USB_EHCI_MX6
    	setup_usb();
    #endif
    
    #ifdef CONFIG_FSL_QSPI
    	board_qspi_init();
    #endif
    
    #ifdef CONFIG_NAND_MXS
    	setup_gpmi_nand();
    #endif
    
    	return 0;
    }
    
    #ifdef CONFIG_CMD_BMODE
    static const struct boot_mode board_boot_modes[] = {
    	/* 4 bit bus width */
    	{"sd1", MAKE_CFGVAL(0x42, 0x20, 0x00, 0x00)},
    	{"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
    	{"qspi1", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
    	{NULL,	 0},
    };
    #endif
    
    int board_late_init(void)
    {
    #ifdef CONFIG_CMD_BMODE
    	add_board_boot_modes(board_boot_modes);
    #endif
    
    #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
    	setenv("board_name", "EVK");
    
    	if (is_mx6ull_9x9_evk())
    		setenv("board_rev", "9X9");
    	else
    		setenv("board_rev", "14X14");
    #endif
    
    #ifdef CONFIG_ENV_IS_IN_MMC
    	board_late_mmc_env_init();
    #endif
    
    	set_wdog_reset((struct wdog_regs *)WDOG1_BASE_ADDR);
    
    	return 0;
    }
    
    int checkboard(void) 
    { 
        if (is_mx6ull_9x9_evk()) 
            puts("Board: MX6ULL 9x9 EVK\n"); 
        else 
            puts("Board: MX6ULL ALIENTEK EMMC\n"); 
     
        return 0; 
    }
    
    #ifdef CONFIG_FSL_FASTBOOT
    void board_fastboot_setup(void)
    {
    	switch (get_boot_device()) {
    #if defined(CONFIG_FASTBOOT_STORAGE_MMC)
    	case SD1_BOOT:
    	case MMC1_BOOT:
    		if (!getenv("fastboot_dev"))
    			setenv("fastboot_dev", "mmc0");
    		if (!getenv("bootcmd"))
    			setenv("bootcmd", "boota mmc0");
    		break;
    	case SD2_BOOT:
    	case MMC2_BOOT:
    		if (!getenv("fastboot_dev"))
    			setenv("fastboot_dev", "mmc1");
    		if (!getenv("bootcmd"))
    			setenv("bootcmd", "boota mmc1");
    		break;
    #endif /*CONFIG_FASTBOOT_STORAGE_MMC*/
    #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
    	case NAND_BOOT:
    		if (!getenv("fastboot_dev"))
    			setenv("fastboot_dev", "nand");
    		if (!getenv("fbparts"))
    			setenv("fbparts", ANDROID_FASTBOOT_NAND_PARTS);
    		if (!getenv("bootcmd"))
    			setenv("bootcmd",
    				"nand read ${loadaddr} ${boot_nand_offset} "
    				"${boot_nand_size};boota ${loadaddr}");
    		break;
    #endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
    
    	default:
    		printf("unsupported boot devices\n");
    		break;
    	}
    }
    
    #ifdef CONFIG_ANDROID_RECOVERY
    int check_recovery_cmd_file(void)
    {
    	int recovery_mode = 0;
    
    	recovery_mode = recovery_check_and_clean_flag();
    
    	return recovery_mode;
    }
    
    void board_recovery_setup(void)
    {
    	int bootdev = get_boot_device();
    
    	switch (bootdev) {
    #if defined(CONFIG_FASTBOOT_STORAGE_MMC)
    	case SD1_BOOT:
    	case MMC1_BOOT:
    		if (!getenv("bootcmd_android_recovery"))
    			setenv("bootcmd_android_recovery", "boota mmc0 recovery");
    		break;
    	case SD2_BOOT:
    	case MMC2_BOOT:
    		if (!getenv("bootcmd_android_recovery"))
    			setenv("bootcmd_android_recovery", "boota mmc1 recovery");
    		break;
    #endif /*CONFIG_FASTBOOT_STORAGE_MMC*/
    #if defined(CONFIG_FASTBOOT_STORAGE_NAND)
    	case NAND_BOOT:
    		if (!getenv("bootcmd_android_recovery"))
    			setenv("bootcmd_android_recovery",
    				"nand read ${loadaddr} ${recovery_nand_offset} "
    				"${recovery_nand_size};boota ${loadaddr}");
    		break;
    #endif /*CONFIG_FASTBOOT_STORAGE_NAND*/
    
    	default:
    		printf("Unsupported bootup device for recovery: dev: %d\n",
    			bootdev);
    		return;
    	}
    
    	printf("setup env for recovery..\n");
    	setenv("bootcmd", "run bootcmd_android_recovery");
    }
    #endif /*CONFIG_ANDROID_RECOVERY*/
    
    #endif /*CONFIG_FSL_FASTBOOT*/
    
    #ifdef CONFIG_SPL_BUILD
    #include 
    #include 
    #include 
    
    
    static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = {
    	.grp_addds = 0x00000030,
    	.grp_ddrmode_ctl = 0x00020000,
    	.grp_b0ds = 0x00000030,
    	.grp_ctlds = 0x00000030,
    	.grp_b1ds = 0x00000030,
    	.grp_ddrpke = 0x00000000,
    	.grp_ddrmode = 0x00020000,
    #ifdef CONFIG_TARGET_MX6UL_9X9_EVK
    	.grp_ddr_type = 0x00080000,
    #else
    	.grp_ddr_type = 0x000c0000,
    #endif
    };
    
    #ifdef CONFIG_TARGET_MX6UL_9X9_EVK
    static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
    	.dram_dqm0 = 0x00000030,
    	.dram_dqm1 = 0x00000030,
    	.dram_ras = 0x00000030,
    	.dram_cas = 0x00000030,
    	.dram_odt0 = 0x00000000,
    	.dram_odt1 = 0x00000000,
    	.dram_sdba2 = 0x00000000,
    	.dram_sdclk_0 = 0x00000030,
    	.dram_sdqs0 = 0x00003030,
    	.dram_sdqs1 = 0x00003030,
    	.dram_reset = 0x00000030,
    };
    
    static struct mx6_mmdc_calibration mx6_mmcd_calib = {
    	.p0_mpwldectrl0 = 0x00000000,
    	.p0_mpdgctrl0 = 0x20000000,
    	.p0_mprddlctl = 0x4040484f,
    	.p0_mpwrdlctl = 0x40405247,
    	.mpzqlp2ctl = 0x1b4700c7,
    };
    
    static struct mx6_lpddr2_cfg mem_ddr = {
    	.mem_speed = 800,
    	.density = 2,
    	.width = 16,
    	.banks = 4,
    	.rowaddr = 14,
    	.coladdr = 10,
    	.trcd_lp = 1500,
    	.trppb_lp = 1500,
    	.trpab_lp = 2000,
    	.trasmin = 4250,
    };
    
    struct mx6_ddr_sysinfo ddr_sysinfo = {
    	.dsize = 0,
    	.cs_density = 18,
    	.ncs = 1,
    	.cs1_mirror = 0,
    	.walat = 0,
    	.ralat = 5,
    	.mif3_mode = 3,
    	.bi_on = 1,
    	.rtt_wr = 0,        /* LPDDR2 does not need rtt_wr rtt_nom */
    	.rtt_nom = 0,
    	.sde_to_rst = 0,    /* LPDDR2 does not need this field */
    	.rst_to_cke = 0x10, /* JEDEC value for LPDDR2: 200us */
    	.ddr_type = DDR_TYPE_LPDDR2,
    };
    
    #else
    static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = {
    	.dram_dqm0 = 0x00000030,
    	.dram_dqm1 = 0x00000030,
    	.dram_ras = 0x00000030,
    	.dram_cas = 0x00000030,
    	.dram_odt0 = 0x00000030,
    	.dram_odt1 = 0x00000030,
    	.dram_sdba2 = 0x00000000,
    	.dram_sdclk_0 = 0x00000008,
    	.dram_sdqs0 = 0x00000038,
    	.dram_sdqs1 = 0x00000030,
    	.dram_reset = 0x00000030,
    };
    
    static struct mx6_mmdc_calibration mx6_mmcd_calib = {
    	.p0_mpwldectrl0 = 0x00070007,
    	.p0_mpdgctrl0 = 0x41490145,
    	.p0_mprddlctl = 0x40404546,
    	.p0_mpwrdlctl = 0x4040524D,
    };
    
    struct mx6_ddr_sysinfo ddr_sysinfo = {
    	.dsize = 0,
    	.cs_density = 20,
    	.ncs = 1,
    	.cs1_mirror = 0,
    	.rtt_wr = 2,
    	.rtt_nom = 1,		/* RTT_Nom = RZQ/2 */
    	.walat = 1,		/* Write additional latency */
    	.ralat = 5,		/* Read additional latency */
    	.mif3_mode = 3,		/* Command prediction working mode */
    	.bi_on = 1,		/* Bank interleaving enabled */
    	.sde_to_rst = 0x10,	/* 14 cycles, 200us (JEDEC default) */
    	.rst_to_cke = 0x23,	/* 33 cycles, 500us (JEDEC default) */
    	.ddr_type = DDR_TYPE_DDR3,
    };
    
    static struct mx6_ddr3_cfg mem_ddr = {
    	.mem_speed = 800,
    	.density = 4,
    	.width = 16,
    	.banks = 8,
    	.rowaddr = 15,
    	.coladdr = 10,
    	.pagesz = 2,
    	.trcd = 1375,
    	.trcmin = 4875,
    	.trasmin = 3500,
    };
    #endif
    
    static void ccgr_init(void)
    {
    	struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
    
    	writel(0xFFFFFFFF, &ccm->CCGR0);
    	writel(0xFFFFFFFF, &ccm->CCGR1);
    	writel(0xFFFFFFFF, &ccm->CCGR2);
    	writel(0xFFFFFFFF, &ccm->CCGR3);
    	writel(0xFFFFFFFF, &ccm->CCGR4);
    	writel(0xFFFFFFFF, &ccm->CCGR5);
    	writel(0xFFFFFFFF, &ccm->CCGR6);
    	writel(0xFFFFFFFF, &ccm->CCGR7);
    }
    
    static void spl_dram_init(void)
    {
    	mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs);
    	mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr);
    }
    
    void board_init_f(ulong dummy)
    {
    	/* setup AIPS and disable watchdog */
    	arch_cpu_init();
    
    	ccgr_init();
    
    	/* iomux and setup of i2c */
    	board_early_init_f();
    
    	/* setup GP timer */
    	timer_init();
    
    	/* UART clocks enabled and gd valid - init serial console */
    	preloader_console_init();
    
    	/* DDR initialization */
    	spl_dram_init();
    
    	/* Clear the BSS. */
    	memset(__bss_start, 0, __bss_end - __bss_start);
    
    	/* load/boot image from boot device */
    	board_init_r(NULL, 0);
    }
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562
    • 563
    • 564
    • 565
    • 566
    • 567
    • 568
    • 569
    • 570
    • 571
    • 572
    • 573
    • 574
    • 575
    • 576
    • 577
    • 578
    • 579
    • 580
    • 581
    • 582
    • 583
    • 584
    • 585
    • 586
    • 587
    • 588
    • 589
    • 590
    • 591
    • 592
    • 593
    • 594
    • 595
    • 596
    • 597
    • 598
    • 599
    • 600
    • 601
    • 602
    • 603
    • 604
    • 605
    • 606
    • 607
    • 608
    • 609
    • 610
    • 611
    • 612
    • 613
    • 614
    • 615
    • 616
    • 617
    • 618
    • 619
    • 620
    • 621
    • 622
    • 623
    • 624
    • 625
    • 626
    • 627
    • 628
    • 629
    • 630
    • 631
    • 632
    • 633
    • 634
    • 635
    • 636
    • 637
    • 638
    • 639
    • 640
    • 641
    • 642
    • 643
    • 644
    • 645
    • 646
    • 647
    • 648
    • 649
    • 650
    • 651
    • 652
    • 653
    • 654
    • 655
    • 656
    • 657
    • 658
    • 659
    • 660
    • 661
    • 662
    • 663
    • 664
    • 665
    • 666
    • 667
    • 668
    • 669
    • 670
    • 671
    • 672
    • 673
    • 674
    • 675
    • 676
    • 677
    • 678
    • 679
    • 680
    • 681
    • 682
    • 683
    • 684
    • 685
    • 686
    • 687
    • 688
    • 689
    • 690
    • 691
    • 692
    • 693
    • 694
    • 695
    • 696
    • 697
    • 698
    • 699
    • 700
    • 701
    • 702
    • 703
    • 704
    • 705
    • 706
    • 707
    • 708
    • 709
    • 710
    • 711
    • 712
    • 713
    • 714
    • 715
    • 716
    • 717
    • 718
    • 719
    • 720
    • 721
    • 722
    • 723
    • 724
    • 725
    • 726
    • 727
    • 728
    • 729
    • 730
    • 731
    • 732
    • 733
    • 734
    • 735
    • 736
    • 737
    • 738
    • 739
    • 740
    • 741
    • 742
    • 743
    • 744
    • 745
    • 746
    • 747
    • 748
    • 749
    • 750
    • 751
    • 752
    • 753
    • 754
    • 755
    • 756
    • 757
    • 758
    • 759
    • 760
    • 761
    • 762
    • 763
    • 764
    • 765
    • 766
    • 767
    • 768
    • 769
    • 770
    • 771
    • 772
    • 773
    • 774
    • 775
    • 776
    • 777
    • 778
    • 779
    • 780
    • 781
    • 782
    • 783
    • 784
    • 785
    • 786
    • 787
    • 788
    • 789
    • 790
    • 791
    • 792
    • 793
    • 794
    • 795
    • 796
    • 797
    • 798
    • 799
    • 800
    • 801
    • 802
    • 803
    • 804
    • 805
    • 806
    • 807
    • 808
    • 809
    • 810
    • 811
    • 812
    • 813
    • 814
    • 815
    • 816
    • 817
    • 818
    • 819
    • 820
    • 821
    • 822
    • 823
    • 824
    • 825
    • 826
    • 827
    • 828
    • 829
    • 830
    • 831
    • 832
    • 833
    • 834
    • 835
    • 836
    • 837
    • 838
    • 839
    • 840
    • 841
    • 842
    • 843
    • 844
    • 845
    • 846
    • 847
    • 848
    • 849
    • 850
    • 851
    • 852
    • 853
    • 854
    • 855
    • 856
    • 857
    • 858
    • 859
    • 860
    • 861
    • 862
    • 863
    • 864
    • 865
    • 866
    • 867
    • 868
    • 869
    • 870
    • 871
    • 872
    • 873
    • 874
    • 875
    • 876
    • 877
    • 878
    • 879
    • 880
    • 881
    • 882
    • 883
    • 884
    • 885
    • 886
    • 887
    • 888
    • 889
    • 890
    • 891
    • 892
    • 893
    • 894
    • 895
    • 896
    • 897
    • 898
    • 899
    • 900
    • 901
    • 902
    • 903
    • 904
    • 905
    • 906
    • 907
    • 908
    • 909
    • 910
    • 911
    • 912
    • 913
    • 914
    • 915
    • 916
    • 917
    • 918
    • 919
    • 920
    • 921
    • 922
    • 923
    • 924
    • 925
    • 926
    • 927
    • 928
    • 929
    • 930
    • 931
    • 932
    • 933
    • 934
    • 935
    • 936
    • 937
    • 938
    • 939
    • 940
    • 941
    • 942
    • 943
    • 944
    • 945
    • 946
    • 947
    • 948
    • 949
    • 950
    • 951
    • 952
    • 953
    • 954
    • 955
    • 956
    • 957
    • 958
    • 959
    • 960
    • 961
    • 962
    • 963
    • 964
    • 965
    • 966
    • 967
    • 968
    • 969
    • 970
    • 971
    • 972
    • 973
    • 974
    • 975
    • 976
    • 977
    • 978
    • 979
    • 980
    • 981
    • 982
    • 983
    • 984
    • 985
    • 986
    • 987
    • 988
    • 989
    • 990
    • 991
    • 992
    • 993
    • 994
    • 995
    • 996
    • 997
    • 998
    • 999
    • 1000
    • 1001
    • 1002
    • 1003
    • 1004
    • 1005
    • 1006
    • 1007
    • 1008
    • 1009
    • 1010
    • 1011
    • 1012
    • 1013
    • 1014
    • 1015
    • 1016
    • 1017
    • 1018
    • 1019
    • 1020
    • 1021
    • 1022
    • 1023
    • 1024
    • 1025
    • 1026
    • 1027
    • 1028
    • 1029
    • 1030
    • 1031
    • 1032
    • 1033
    • 1034
    • 1035
    • 1036
    • 1037
    • 1038
    • 1039
    • 1040
    • 1041
    • 1042
    • 1043
    • 1044
    • 1045
    • 1046
    • 1047
    • 1048
    • 1049
    • 1050
    • 1051
    • 1052
    • 1053
    • 1054
    • 1055
    • 1056
    • 1057
    • 1058
    • 1059
    • 1060
    • 1061
    • 1062
    • 1063
    • 1064
    • 1065
    • 1066
    • 1067
    • 1068
    • 1069
    • 1070
    • 1071
    • 1072
    • 1073
    • 1074
    • 1075
    • 1076
    • 1077
    • 1078
  • 相关阅读:
    .NET周刊【12月第1期 2023-12-06】
    【javaSE】 Lambda表达式与Lambda表达式的使用
    1.2 向量代数
    QPlainTextEdit
    不小心清空了回收站怎么恢复,回收站删除的东西可以恢复吗
    一文读懂二分查找(插入)算法
    nvidia-1080服务器上离线安装mmdetection2.23步骤
    CSS -- a:link 失效问题 及 属性选择器
    面试题:深拷贝、浅拷贝、引用拷贝的区别
    LeetCode 热题 HOT 100 第七十六天 394. 字符串解码 中等题 用python3求解
  • 原文地址:https://blog.csdn.net/qq_38863842/article/details/127875140