在线时间19 小时
UID3173502
注册时间2015-10-21
NXP金币0
TA的每日心情 | 开心 2021-2-25 16:17 |
---|
签到天数: 2 天 连续签到: 1 天 [LV.1]初来乍到
注册会员

- 积分
- 179
- 最后登录
- 2021-11-3
|
本帖最后由 杨帆!起航! 于 2016-9-23 10:58 编辑
拓展16C554时,用到CS0片选,首先用需要配置EIM总线
/* These registers settings are just valid for Numonyx M29W256GL7AN6E. */
static void mx6q_setup_weimcs(void)
{
void __iomem *nor_reg = MX6_IO_ADDRESS(WEIM_BASE_ADDR);
void __iomem *ccm_reg = MX6_IO_ADDRESS(CCM_BASE_ADDR);
unsigned int reg;
struct clk *clk;
u32 rate;
/* CLKCTL_CCGR6: Set emi_slow_clock to be on in all modes */
reg = readl(ccm_reg + 0x80);
reg |= 0x00000C00;
writel(reg, ccm_reg + 0x80);
/* Timing settings below based upon datasheet for M29W256GL7AN6E
These setting assume that the EIM_SLOW_CLOCK is set to 132 MHz */
clk = clk_get(NULL, "emi_slow_clk");
if (IS_ERR(clk))
printk(KERN_ERR "emi_slow_clk not found\n");
rate = clk_get_rate(clk);
if (rate != 132000000)
printk(KERN_ERR "Warning: emi_slow_clk not set to 132 MHz!"
" WEIM NOR timing may be incorrect!\n");
/*
* For EIM General Configuration registers.
*
* CS0GCR1:
* GBC = 0; CSREC = 6; DSZ = 2; BL = 0;
* CREP = 1; CSEN = 1;
*
* EIM Operation Mode: MUM = SRD = SWR = 0.
* (Async write/Async page read, none multiplexed)
*
* CS0GCR2:
* ADH = 1
*/
writel(0x00620081, nor_reg);
writel(0x00000001, nor_reg + 0x00000004);
/*
* For EIM Read Configuration registers.
*
* CS0RCR1:
* RWSC = 1C;
* RADVA = 0; RADVN = 2;
* OEA = 2; OEN = 0;
* RCSA = 0; RCSN = 0
*
* CS0RCR2:
* APR = 1 (Async Page Read);
* PAT = 4 (6 EIM clock sycles)
*/
writel(0x1C022000, nor_reg + 0x00000008);
writel(0x0000C000, nor_reg + 0x0000000C);
/*
* For EIM Write Configuration registers.
*
* CS0WCR1:
* WWSC = 20;
* WADVA = 0; WADVN = 1;
* WBEA = 1; WBEN = 2;
* WEA = 1; WEN = 6;
* WCSA = 1; WCSN = 2;
*
* CS0WCR2:
* WBCDD = 0
*/
writel(0x1404a38e, nor_reg + 0x00000010);
writel(0x00000000, nor_reg + 0x00000014);
}
6个寄存器的配置
3364 writel(0x00660081, nor_reg + 0x00000000); 片选0 128M 映射空间 数据线16-23 8位的
3365 writel(0x00000001, nor_reg + 0x00000004);
3366 writel(0x1c022000, nor_reg + 0x00000008);
3367 writel(0x0000C000, nor_reg + 0x0000000c);
3368 writel(0x1404a38e, nor_reg + 0x00000010);
3369 writel(0x00000000, nor_reg + 0x00000014);
3370 writel(0x00000001, nor_reg + 0x90);
3371 printk("GPR1__CSx____is____end%x\n",reg);
增加拓展串口功能
kernel_imx/drivers/tty/serial/8250_exar_st16c554.c
16 #define PORT(_base,_irq) \
17 { \
18 .iobase = _base, \
19 .irq = _irq, \
20 .uartclk = 11059200, \
21 .iotype = UPIO_PORT, \
22 .flags = UPF_BOOT_AUTOCONF, \
23 }
24 #define CS0_BASE 0x08000000 //add cjf-_-
25
26 #define CARD1_BASE CS0_BASE + 0x10
27 #define CARD2_BASE CS0_BASE + 0x20
28 #define CARD3_BASE CS0_BASE + 0x30
29 #define CARD4_BASE CS0_BASE + 0x40
30
31 #define 16C554_INTA gpio_to_irq(IMX_GPIO_NR(1,10))
32 #define 16C554_INTB gpio_to_irq(IMX_GPIO_NR(1,15))
33 #define 16C554_INTC gpio_to_irq(IMX_GPIO_NR(1,14))
34 #define 16C554_INTD gpio_to_irq(IMX_GPIO_NR(1,11))
35
36 static struct plat_serial8250_port exar_data[] = {
37 PORT(CARD1_BASE, 16C554_INTA),
38 PORT(CARD2_BASE, 16C554_INTB),
39 PORT(CARD3_BASE, 16C554_INTC),
40 PORT(CARD4_BASE, 16C554_INTD),
41 { },
42 };
需要注意的地方:
membase:该成员描述的该串口接口寄存器虚拟地址的基地址。在初始化该成员时,需要自己把该串口接口寄存器的物理地址映射到虚拟地址空间。并且该映射工作需要在内核的板级初始化阶段完成。
.mapbase指的是16C554的物理基地址,注意不是membase;
.uartclk是16C554晶振的频率,其最高波特率为.uartclk/16;
.iotype指的是访问类型,与硬件的连接相关,
UPIO_PORT 端口地址,8位
UPIO_HUB6
UPIO_MEM 8位的内存地址
UPIO_MEM32 32位的内存地址
UPIO_MEM32表示为32位总线访问方式,即访问16C554的寄存器时,读取32位数,取低8位;
.regshift也跟硬件的物理连接相关,指的是访问16C554的每个地址时的偏移,也就是16C554的A0对应CPU的A几;
UPF_IOREMAP指16C554寄存器需要映射到虚拟地址访问;
8250.c 实行工作流程
serial8250_register_ports
serial8250_isa_init_ports
platform_driver_register
serial8250_isa_driver
serial8250_probe 4次循环{
serial8250_register_port
uart_add_one_port -> (文件serial_core.c) uart_configure_port->uart_report_port(打印串口信息)
uart_ops serial8250_pops
serial8250_config_port
autoconfig
autoconfig_16550a
autoconfig_16550a
uart_config
}
|
|