uboot移植2

1.LCD 驱动修改

一般 uboot 中修改驱动基本都是在 xxx.h 和 xxx.c 这两个文件中进行的,xxx 为板子名称,比如 mx6ull_hnor_emmc.h 和 mx6ull_hnor_emmc.c 这两个文件

一般修改 LCD 驱动重点注意以下几点:
①、LCD 所使用的 GPIO,查看 uboot 中 LCD 的 IO 配置是否正确。
②、LCD 背光引脚 GPIO 的配置。
③、LCD 配置参数是否正确。

I.MX6U-ALPHA 开发板 LCD 原理图和 NXP 官方 I.MX6ULL 开发板一致,也就是 LCD 的 IO 和背光 IO 都一样的,所以 IO 部分就不用修改了。需要修改第三项 LCD 参数。

使用 cd board/freescale/mx6ull_hnor_emmc 进入mx6ull_hnor_emmc目录,打开mx6ull_hnor_emmc.c文件。找到如下所示内容:

 780 struct display_info_t const displays[] = {{
 781     .bus = MX6UL_LCDIF1_BASE_ADDR,
 782     .addr = 0,
 783     .pixfmt = 24,
 784     .detect = NULL,
 785     .enable = do_enable_parallel_lcd,
 786     .mode   = {
 787         .name           = "TFT43AB",
 788         .xres           = 480,
 789         .yres           = 272,
 790         .pixclock       = 108695,
 791         .left_margin    = 8,
 792         .right_margin   = 4,
 793         .upper_margin   = 2,
 794         .lower_margin   = 4,
 795         .hsync_len      = 41,
 796         .vsync_len      = 10,
 797         .sync           = 0,
 798         .vmode          = FB_VMODE_NONINTERLACED
 799 } } };

示例代码中定义了一个变量 displays,类型为 display_info_t,这个结构体是 LCD信息结构体,其中包括了 LCD 的分辨率,像素格式,LCD 的各个参数等。

display_info_t 定义在文件 arch/arm/include/asm/imx-common/video.h 中,定义如下:
 

 17 struct display_info_t {
 18     int bus;
 19     int addr;
 20     int pixfmt;
 21     int (*detect)(struct display_info_t const *dev);
 22     void    (*enable)(struct display_info_t const *dev);
 23     struct  fb_videomode mode;
 24 };

pixfmt 是像素格式,也就是一个像素点是多少位,如果是 RGB565 的话就是 16 位,如果是 888 的话就是 24 位,一般使用 RGB888。结构体 display_info_t 还有个 mode 成员变量,此成员变量也是个结构体,为 fb_videomode,定义在文件 include/linux/fb.h 中,定义如下:
 

598 struct fb_videomode {
599     const char *name;   /* optional */
600     u32 refresh;        /* optional */
601     u32 xres;
602     u32 yres;
603     u32 pixclock;
604     u32 left_margin;
605     u32 right_margin;
606     u32 upper_margin;
607     u32 lower_margin;
608     u32 hsync_len;
609     u32 vsync_len;
610     u32 sync;
611     u32 vmode;
612     u32 flag;
613 };

结构体 fb_videomode 里面的成员变量为 LCD 的参数,这些成员变量函数如下:
name:LCD 名字,要和环境变量中的 panel 相等。
xres、yres:LCD X 轴和 Y 轴像素数量。
pixclock:像素时钟,每个像素时钟周期的长度,单位为皮秒。
left_margin:HBP,水平同步后肩。
right_margin:HFP,水平同步前肩。
upper_margin:VBP,垂直同步后肩。
lower_margin:VFP,垂直同步前肩。
hsync_len:HSPW,行同步脉宽。
vsync_len:VSPW,垂直同步脉宽。
vmode:大多数使用 FB_VMODE_NONINTERLACED,也就是不使用隔行扫描。

正点原子的 7 寸 1024*600 分辨率的屏幕(ATK7016)屏幕要求的像素时钟为 51.2MHz,因此:
pixclock=(1/51200000)*10^12=19531

根据其他的屏幕参数,可以得出 ATK7016 屏幕的配置参数如下:

 780 struct display_info_t const displays[] = {{
 781     .bus = MX6UL_LCDIF1_BASE_ADDR,
 782     .addr = 0,
 783     .pixfmt = 24,
 784     .detect = NULL,
 785     .enable = do_enable_parallel_lcd,
 786     .mode   = {
 787         .name           = "TFT7016",
 788         .xres           = 1024,
 789         .yres           = 600,
 790         .pixclock       = 19531,
 791         .left_margin    = 140,
 792         .right_margin   = 160,
 793         .upper_margin   = 20,
 794         .lower_margin   = 12,
 795         .hsync_len      = 20,
 796         .vsync_len      = 3,
 797         .sync           = 0,
 798         .vmode          = FB_VMODE_NONINTERLACED
 799 } } };

打开 mx6ull_alientek_emmc.h,找到所有如下语句:

panel=TFT43AB

将其改为:

panel=TFT7016

也就是设置 panel 为 TFT7016,panel 的值要与代码中的.name 成员变量的值一致。修改完成以后重新编译一遍 uboot 并烧写到 SD 中启动。

2.7 网络驱动修改


1、I.MX6U-ALPHA 开发板网络简介
I.MX6UL/ULL 内部有个以太网 MAC 外设,也就是 ENET,需要外接一个 PHY 芯片来实现网络通信功能,也就是内部 MAC+外部 PHY 芯片的方案。I.MX6UL/ULL 有两个网络接口 ENET1 和 ENET2,正点原子的 I.MX6U-ALPHA 开发板提供了这两个网络接口,其中 ENET1 和 ENET2 都使用 LAN8720A 作为 PHY 芯片。NXP 官方的I.MX6ULL EVK 开发板使用 KSZ8081 这颗 PHY 芯片,正点原子的 I.MX6U-ALPHA 开发板将 ENET1 和 ENET2的 PHY 换成了 LAN8720A。

接下来调整网络驱动,使网络工作正常。
我们要修改 ENET1 网络驱动的话重点就三点:
①、ENET1 复位引脚初始化。
②、LAN8720A 的器件 ID。
③、LAN8720 驱动

关于 ENET2 网络驱动的修改也注意一下三点
①、ENET2 的复位引脚,从上图可以看出,ENET2 的复位引脚 ENET2_RST 接到了
I.MX6ULL 的 SNVS_TAMPER8 上。
②、ENET2 所使用的 PHY 芯片器件地址,从上图可以看出,PHY 器件地址为 0X1。
③、LAN8720 驱动,ENET1 和 ENET2 都使用的 LAN8720,所以驱动肯定是一样的。
2、网络 PHY 地址修改
首先修改 uboot 中的 ENET1 和 ENET2 的 PHY 地址和驱动,打开 mx6ull_hnor_emmc.h这个文件,找到如下代码:

318 #ifdef CONFIG_CMD_NET
319 #define CONFIG_CMD_PING
320 #define CONFIG_CMD_DHCP
321 #define CONFIG_CMD_MII
322 #define CONFIG_FEC_MXC
323 #define CONFIG_MII
324 #define CONFIG_FEC_ENET_DEV 1
325 
326 #if (CONFIG_FEC_ENET_DEV == 0)
327 #define IMX_FEC_BASE ENET_BASE_ADDR
328 #define CONFIG_FEC_MXC_PHYADDR 0x2
329 #define CONFIG_FEC_XCV_TYPE RMII
330 #elif (CONFIG_FEC_ENET_DEV == 1)
331 #define IMX_FEC_BASE ENET2_BASE_ADDR
332 #define CONFIG_FEC_MXC_PHYADDR 0x1
333 #define CONFIG_FEC_XCV_TYPE RMII
334 #endif
335 #define CONFIG_ETHPRIME "FEC"
336 
337 #define CONFIG_PHYLIB
338 #define CONFIG_PHY_MICREL
339 #endif


 324 行的宏 CONFIG_FEC_ENET_DEV 用于选择使用哪个网口,默认为 1,也就是选择ENET2。第 328 行为 ENET1 的 PHY 地址,默认是 0X2,第 332行为 ENET2 的 PHY 地址,默认为 0x1。根据前面的分析可知,正点原子的 I.MX6U-ALPHA 开发板 ENET1 的 PHY 地址为0X0,ENET2 的 PHY 地址为 0X1,所以需要将第 328行的宏 CONFIG_FEC_MXC_PHYADDR改为 0x0。

第 338 行定了一个宏 CONFIG_PHY_MICREL,此宏用于使能 uboot 中 Micrel 公司的 PHY驱动,KSZ8081 这颗 PHY 芯片就是 Micrel 公司生产的,不过 Micrel 已经被 Microchip 收购了。如果要使用 LAN8720A,那么就得将 CONFIG_PHY_MICREL 改为 CONFIG_PHY_SMSC,也就是使能 uboot 中的 SMSC 公司中的 PHY 驱动,因为 LAN8720A 就是 SMSC 公司生产的。所以以上示例代码有三处要修改:
①、修改 ENET1 网络 PHY 的地址。
②、修改 ENET2 网络 PHY 的地址。
③、使能 SMSC 公司的 PHY 驱动。
修改后的网络 PHY 地址参数如下所示:
 

318 #ifdef CONFIG_CMD_NET
319 #define CONFIG_CMD_PING
320 #define CONFIG_CMD_DHCP
321 #define CONFIG_CMD_MII
322 #define CONFIG_FEC_MXC
323 #define CONFIG_MII
324 #define CONFIG_FEC_ENET_DEV 1
325 
326 #if (CONFIG_FEC_ENET_DEV == 0)
327 #define IMX_FEC_BASE ENET_BASE_ADDR
328 #define CONFIG_FEC_MXC_PHYADDR 0x0
329 #define CONFIG_FEC_XCV_TYPE RMII
330 #elif (CONFIG_FEC_ENET_DEV == 1)
331 #define IMX_FEC_BASE ENET2_BASE_ADDR
332 #define CONFIG_FEC_MXC_PHYADDR 0x1
333 #define CONFIG_FEC_XCV_TYPE RMII
334 #endif
335 #define CONFIG_ETHPRIME "FEC"
336 
337 #define CONFIG_PHYLIB
338 #define CONFIG_PHY_SMSC
339 #endif

3、删除 uboot 中 74LV595 的驱动代码

uboot 中网络 PHY 芯片地址修改完成以后就是网络复位引脚的驱动修改了,打开mx6ull_hnor_emmc.c,找到如下代码:

 91 #define IOX_SDI IMX_GPIO_NR(5, 10)
  92 #define IOX_STCP IMX_GPIO_NR(5, 7)
  93 #define IOX_SHCP IMX_GPIO_NR(5, 11)
  94 #define IOX_OE IMX_GPIO_NR(5, 8)

示例代码 中以 IOX 开头的宏定义是 74LV595 的相关 GPIO,因为 NXP 官方I.MX6ULL EVK 开发板使用 74LV595 来扩展 IO,两个网络的复位引脚就是由 74LV595 来控制的。正点原子的 I.MX6U-ALPHA 开发板并没有使用 74LV595,因此我们将示例代码中的代码删除掉,替换为如下所示代码:
 

  91 #define ENET1_RESET IMX_GPIO_NR(5, 7)
  92 #define ENET2_RESET IMX_GPIO_NR(5, 8)

ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07,ENET2 的复位引脚连
接到 SNVS_TAMPER8 上,对应 GPIO5_IO08。

继续在 mx6ull_hnor_emmc.c 中找到如下代码:

static iomux_v3_cfg_t const iox_pads[] = {
	/* IOX_SDI */
	MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
	/* IOX_SHCP */
	MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
	/* IOX_STCP */
	MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
	/* IOX_nOE */
	MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

同理,上述示例代码是 74LV595 的 IO 配置参数结构体,将其删除掉。继续在mx6ull_alientek_emmc.c 中找到函数 iox74lv_init和iox74lv_set,如下所示:

static void iox74lv_init(void)
{
	int i;

	gpio_direction_output(IOX_OE, 0);

	for (i = 7; i >= 0; i--)
	{
		gpio_direction_output(IOX_SHCP, 0);
		gpio_direction_output(IOX_SDI, seq[qn_output[i]][0]);
		udelay(500);
		gpio_direction_output(IOX_SHCP, 1);
		udelay(500);
	}

	gpio_direction_output(IOX_STCP, 0);
	udelay(500);
	/*
	 * shift register will be output to pins
	 */
	gpio_direction_output(IOX_STCP, 1);

	for (i = 7; i >= 0; i--)
	{
		gpio_direction_output(IOX_SHCP, 0);
		gpio_direction_output(IOX_SDI, seq[qn_output[i]][1]);
		udelay(500);
		gpio_direction_output(IOX_SHCP, 1);
		udelay(500);
	}
	gpio_direction_output(IOX_STCP, 0);
	udelay(500);
	/*
	 * shift register will be output to pins
	 */
	gpio_direction_output(IOX_STCP, 1);
};

void iox74lv_set(int index)
{
	int i;

	for (i = 7; i >= 0; i--)
	{
		gpio_direction_output(IOX_SHCP, 0);

		if (i == index)
			gpio_direction_output(IOX_SDI, seq[qn_output[i]][0]);
		else
			gpio_direction_output(IOX_SDI, seq[qn_output[i]][1]);
		udelay(500);
		gpio_direction_output(IOX_SHCP, 1);
		udelay(500);
	}

	gpio_direction_output(IOX_STCP, 0);
	udelay(500);
	/*
	  * shift register will be output to pins
	  */
	gpio_direction_output(IOX_STCP, 1);

	for (i = 7; i >= 0; i--)
	{
		gpio_direction_output(IOX_SHCP, 0);
		gpio_direction_output(IOX_SDI, seq[qn_output[i]][1]);
		udelay(500);
		gpio_direction_output(IOX_SHCP, 1);
		udelay(500);
	}

	gpio_direction_output(IOX_STCP, 0);
	udelay(500);
	/*
	  * shift register will be output to pins
	  */
	gpio_direction_output(IOX_STCP, 1);
};

iox74lv_init 函数是 74LV595 的初始化函数,iox74lv_set 函数用于控制 74LV595 的 IO 输出电平,将这两个函数全部删除掉!

在 mx6ull_hnor_emmc.c 中找到 board_init 函数,此函数是板子初始化函数,会被board_init_r 调用,board_init 函数内容如下:

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;
}


board_init 会调用 imx_iomux_v3_setup_multiple_pads 和 iox74lv_init 这两个函数来初始化74lv595 的 GPIO,将这两行删除掉。至此,mx6ull_znn_emmc.c 中关于 74LV595 芯片的驱动代码都删除掉了,接下来就是添加 I.MX6U-ALPHA 开发板两个网络复位引脚了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值