【NXP IMX系列】UBOOT 板载IO时钟移植配置

本文详细介绍了IMX系列处理器的IOMUX配置,涉及IOMUXC控制器、ALT模式、引脚控制寄存器、时钟设置以及在uboot中如UART、网卡、LCD和USB的配置示例。重点讲解了如何通过IOMUX实现引脚的多路复用和配置,以及CCM模块在时钟控制中的作用。

1 外设配置

LINUX驱动与数据模型中,驱动不变,配置可变。
  • IOMUX 配置
  • CCM 时钟配置
    uboot\board\freescale\mx6ul_14x14_evk\mx6ul_14x14_evk.c中,基本主要代码均与IOMUX和时钟配置有关,下述文章主要介绍IMX系列中的IOMUX配置;

2 i.MX IOMUX Controller

2.1 IOMUX 简介

i.MX BSP Porting Guide Chapter 2 Configuring the IOMUX Controller 在使用 i.MX 引脚(或引脚)之前,用户必须选择所需的功能以及电压级别、驱动强度和滞后等特性的正确值。您可以从 IOMUX 控制器配置一组寄存器。
设置 IOMUX 控制器寄存器的信息如下:

IOMUX 控制器包含四组寄存器,影响 i.MX 6Dual/6Quad/6DualLite/6Solo/6SoloLite/6SoloX/6UltraLite/7Dual 寄存器。

  • 通用寄存器(IOMUXC_GPRx)- 包括控制 PLL 频率、电压和其他通用设置的寄存器。
  • “Daisy Chain” 控制寄存器(IOMUXC_<Instance_port>_SELECT_INPUT)- 当多个引脚可能驱动模块输入时,控制到模块的输入路径。它们允许选择模块的适当输入源。
  • MUX 控制寄存器(更改引脚模式):
    • 选择引脚的八种不同功能(也称为ALT模式)中使用的功能。
    • 使用以下寄存器之一,可以单独或按组设置引脚功能:
      • IOMUXC_SW_MUX_CTL_PAD_
      • IOMUXC_SW_MUX_CTL_GRP_
    • 引脚控制寄存器(更改引脚特性):
      使用以下寄存器之一,可以单独或按组设置引脚特性:
      • IOMUXC_SW_PAD_CTL_PAD_<PAD_NAME>
      • IOMUXC_SW_PAD_CTL_GRP_
    • 引脚特性包括:
      • SRE(1位斜率控制)- 斜率控制位;选择快速/慢速斜率输出。快速斜率用于高频设计。
      • DSE(2位驱动强度控制)- 驱动强度控制位;选择驱动强度(低、中、高或最大)。
      • ODE(1位开漏控制)- 开漏使能位;选择开漏或CMOS输出。
      • HYS(1位滞后控制)- 当引脚为输入时,选择CMOS或施密特触发器。
      • PUS(2位上拉/下拉配置值)- 选择上拉或下拉及其值。
      • PUE(1位上拉/保持选择)- 选择上拉或保持。保持电路有助于确保引脚在不再被驱动时保持在最后的逻辑状态。
      • PKE(1位启用/禁用上拉、下拉或保持能力)- 启用或禁用上拉、下拉或保持。
      • DDR_MODE_SEL(1位 DDR 模式控制)- 与DDR存储器接口时需要。
      • DDR_INPUT(1位 DDR 输入控制)- 与DDR存储器接口时需要。

2.2 Chapter 32 IOMUX Controller (IOMUXC)示例

32.1 Overview

IOMUX控制器(IOMUXC)与IOMUX一起,使芯片能够将一个引脚共享给多个功能块。这是通过对引脚的输入和输出信号进行复用来实现的。每个模块都需要特定的引脚设置(如上拉或保持),对于每个引脚,有多达8个多路复用选项(称为ALT模式)。引脚设置参数由IOMUXC控制。IOMUX仅由几个基本的IOMUX单元组合而成的组合逻辑。每个基本的IOMUX单元只处理一个引脚信号的多路复用。
图32-1说明了系统中IOMUX/IOMUXC的连接性。
在这里插入图片描述

32.1.1 特性

IOMUXC的特性包括:

  • • 32位软件MUX控制寄存器(IOMUXC_SW_MUX_CTL_PAD_或IOMUXC_SW_MUX_CTL_GRP_)用于配置每个引脚的8个备选(ALT)MUX_MODE字段中的一个或预定义的一组引脚,并启用强制选择引脚输入路径(SION位)。
  • • 32位软件引脚控制寄存器(IOMUXC_SW_PAD_CTL_PAD_<PAD_NAME>或IOMUXC_SW_PAD_CTL_GRP_)用于配置每个引脚的特定引脚设置,或预定义的一组引脚。
  • • 32位通用寄存器-根据SoC要求可用的14个(GPR0至GPR13)32位寄存器,可用于任何用途。
  • • 32位输入选择控制寄存器用于控制模块的输入路径,当多个引脚驱动该模块的输入时。
    每个SW MUX/PAD CTL IOMUXC寄存器仅处理一个引脚或一个引脚组。硬件仅实现软件所需的最小寄存器数。例如,如果仅在Pad x上使用ALT0和ALT1模式,则只生成一个位寄存器作为Pad x的软件MUX控制寄存器中的MUX_MODE控制字段。
    软件MUX控制寄存器可以允许强制引脚成为输入(启用输入路径),而不考虑功能方向的驱动。这对于环回和GPIO数据捕获可能有用。

32.2 时钟

这里的表格描述了IOMUXC的时钟源。
有关时钟设置、配置和门控信息,请参阅时钟控制器模块(CCM)。
在这里插入图片描述

32.3 功能描述

本节提供了该模块的完整功能描述。
IOMUXC由两个子模块组成:

  • IOMUXC_REGISTERS 包括所有IOMUXC寄存器(请参阅特性)—寄存器组
  • IOMUXC_LOGIC 包括所有IOMUXC组合逻辑(IP接口控制、地址译码器、可观察多路器)—硬件逻辑线路,通常包含多路选择器
    IOMUX由若干基本iomux_cell单元组成(大约与SoC中的引脚数相当)。如果特定引脚仅需要一种功能模式,则无需使用IOMUX,信号可以直接从模块连接到I/O。
    只有当特定引脚需要两种或更多功能模式,或者需要一种功能模式和一种测试模式时,才需要IOMUX单元。
    基本的iomux_cell设计允许两级硬件信号控制(在ALT6和ALT7模式中,ALT7具有最高优先级),如图32-2所示。
    在这里插入图片描述
32.3.1 ALT6和ALT7扩展多路复用模式

ALT7和ALT6扩展多路复用模式允许系统中的任何信号(例如保险丝、引脚输入、JTAG或软件寄存器)覆盖任何软件配置,并强制使用ALT6/ALT7多路复用模式。
它还允许一个IOMUX软件寄存器控制一组引脚。

32.3.2 通过SION位进行软件环回

存在一种有限的选项,可以覆盖默认的引脚功能,并强制输入路径处于活动状态(ipp_ibe==1’b1),而不管对应模块驱动的值是多少。
这可以通过将IOMUXC_SW_MUX_CTL寄存器中的SION(软件输入开启)位(如果可用)设置为“1”来实现。
用途包括:
• 环回测试 - 模块x驱动引脚并将其作为输入接收相应的值。
• GPIO捕获 - 模块x驱动引脚,该值被GPIO捕获。

32.3.3 Daisy chain - 多个引脚驱动同一模块输入引脚

在某些情况下,多个引脚可能驱动单个模块的输入引脚。这种情况需要增加一个IOMUX层级;所有这些输入信号都经过多路复用,并且专用的软件控制寄存器控制多路复用以选择所需的输入路径。
参与“链接”的模块端口需要两个软件配置命令,一个用于选择此引脚的模式(可通过IOMUXC_SW_MUX_CTL_PAD> registers),另一个用于将其定义为输入路径(通过链接寄存器)。
这意味着参与“链接”的模块端口需要两个软件配置命令,一个用于选择此引脚的模式(可通过IOMUXC_SW_MUX_CTL_PAD>寄存器编程),另一个用于将其定义为输入路径(通过daisy chain 寄存器)。链接示意图如下所示。

在这里插入图片描述

MUX/PAD/SELECT寄存器

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如何根据原理图找寄存器

在这里插入图片描述
一般PAD引脚标注第一个引用即为寄存器名字,如JTAG_TCK,JTAG_TMS,
对应的俩主要寄存器为:
IOMUXC_SW_MUX_CTL_PAD_JTAG_TCK,主要用于配置选择该引脚功能选择为: SJC_TCK of instance: sjc,GPT2_COMPARE2 of instance: gpt2,SAI2_RX_DATA of instance: sai2,PWM7_OUT of instance: pwm7,GPIO1_IO14 of instance: gpio1,SIM2_POWER_FAIL of instance: sim2 其中的一种;
IOMUXC_SW_PAD_CTL_PAD_JTAG_TCK:则用于配置当前pad引脚 的电气特性,一般可根据硬件设计师建议配置;

2.3 Chapter 4 External Signals and Pin Multiplexing

该芯片包含有限数量的引脚,其中大多数具有多个信号选项。
这些信号到引脚和引脚到信号的选项是通过输入输出多路复用器(IOMUX)来选择的。IOMUX还用于配置其他引脚特性,如电压级别、驱动强度和滞后。
多路复用选项表列出了按模块实例分组的外部信号,每个信号的多路复用选项以及用于将信号路由到所选引脚的寄存器。
下图意味着I2C2需要俩PORT也即SCL和SDA,通常SCL可以配置为CSI_HSYNC、GPIO1_IO00,UART5_TX_DATA或者其他选择,具体引脚分配由硬件工程师设计分配,软件工程师需要在板级初始化函数中配置相应pad和mux mode;
在这里插入图片描述

2.4 UBOOT代码解析

2.4.1 UART 引脚配置

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

其中

MX6_PAD_UART1_TX_DATA__UART1_DCE_TX                   = IOMUX_PAD(0x0310, 0x0084, 0, 0x0000, 0, 0),
MX6_PAD_UART1_TX_DATA__UART1_DTE_RX                   = IOMUX_PAD(0x0310, 0x0088, 0, 0x0624, 2, 0),

位于 uboot\arch\arm\include\asm\arch-mx6/ mx6ull_pins.h 中

#define IOMUX_PAD(pad_ctrl_ofs, mux_ctrl_ofs, mux_mode, sel_input_ofs,	\
		sel_input, pad_ctrl)					\
	(((iomux_cfg_t)(mux_ctrl_ofs) << MUX_CTRL_OFS_SHIFT)     |	\
	((iomux_cfg_t)(mux_mode)      << MUX_MODE_SHIFT)         |	\
	((iomux_cfg_t)(pad_ctrl)      << MUX_PAD_CTRL_SHIFT)     |	\
	((iomux_cfg_t)(sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT)|	\
	((iomux_cfg_t)(sel_input)     << MUX_SEL_INPUT_SHIFT))

其中

mux_reg:mux控制寄存器偏移地址
conf_reg:pad控制寄存器偏移地址
input_reg:select_input控制寄存器偏移地址
mux_mode:mux模式
input_val:select_input寄存器值

在 IMX6ULLRM文档中可以查到如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在 TX中 sel_input_ofs为0,在RX 中配置为0x0624
在这里插入图片描述
在这里插入图片描述
暂时对MX6_PAD_UART1_TX_DATA__UART1_DTE_RX = IOMUX_PAD(0x0310, 0x0088, 0, 0x0624, 2, 0), 的设置为 310和2 俩个数据不理解,后续分析;

引脚配置:

#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)
void board_init_f(ulong dummy)
{
	ccgr_init();

	/* setup AIPS and disable watchdog */
	arch_cpu_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);
}
int board_early_init_f(void)
{
	setup_iomux_uart();

	return 0;
}
static void setup_iomux_uart(void)
{
	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
}

void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t pad) 函数实现PIN IOMUX初始化的最终配置与执行;

2.4.2 网卡配置

uboot\board\freescale\mx6ul_14x14_evk\mx6ul_14x14_evk.c.c中

#ifdef CONFIG_FEC_MXC
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

在函数 setup_fec 中 iomuxc_regs->gpr 即下述寄存器

在这里插入图片描述
在这里插入图片描述

2. 4.3 LCD 配置

static int setup_lcd(void)
{
	enable_lcdif_clock(LCDIF1_BASE_ADDR, 1);

	imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads));

	/* Reset the LCD */
	gpio_request(IMX_GPIO_NR(5, 9), "lcd reset");
	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_request(IMX_GPIO_NR(1, 8), "backlight");
	gpio_direction_output(IMX_GPIO_NR(1, 8) , 1);

	return 0;
}
#else
static inline int setup_lcd(void) { return 0; }
#endif

2.4.4 USB 引脚配置

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

3 CCM

Chapter 18
Clock Controller Module (CCM)时钟控制
在 uboot\board\freescale\mx6ul_14x14_evk\mx6ul_14x14_evk.c中

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

详细有关时钟电源管理介绍,请参考后续文章;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值