EIM总线驱动移植(一)

本文详述了在iMX6Q ARM平台上移植EIM总线驱动的具体步骤,包括添加驱动文件、配置引脚、初始化设备、注册设备及内核编译等过程。经FPGA验证,已实现基本时序逻辑,但仍需进一步优化以确保数据读写正确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:公司现有的开发板内核没有EIM总线驱动,在百度上找了一下文章都说很简单,驱动一配什么的就好了,自己做了一份,通过FPGA查看,各个引脚均无反应。。。前一阵,发现飞凌开发板提供了该驱动,于是便搞了一套。。。

ARM平台:iMX6Q

Linux版本:3.0.35

1、将driver\misc\fpga.c文件拷贝到现有内核同路径文件夹下,同时修改Makefile文件,编译时自动编入内核;

obj-y                += fpga.o

2、在arch/arm/mach-mx6/board-mx6q_xxxx.h中增加weim引脚定义

static iomux_v3_cfg_t mx6q_weimram_pads[] __initdata = {
        /* Parallel NOR */
        MX6Q_PAD_EIM_OE__WEIM_WEIM_OE,
        MX6Q_PAD_EIM_RW__WEIM_WEIM_RW,
        MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT,
        MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0,
//      MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0,
        MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1,
        MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2,
        MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3,
        /*Control NOR reset using gpio mode*/
        //MX6Q_PAD_DISP0_DAT8__GPIO_4_29,

        MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA,
        MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK,
        /* Parallel Nor Data Bus */
        MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16,
        MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17,
        MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18,
        MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19,
        MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20,
        MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21,
        MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22,
        MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23,
        MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24,
        MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25,
        MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26,
        MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27,
        MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28,
        MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29,
        MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30,
        MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31,

        /* Parallel Nor 25 bit Address Bus */
        /* Parallel Ram 19 bit Address Bus */
        //MX6Q_PAD_EIM_A24__GPIO_5_4,
        MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25,//bs add       
        MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24,//bs add
        MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23,
        MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22,
        MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21,
        MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20,
        MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19,
        MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18,
        MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17,
        MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16,

        MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15,
        MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14,
        MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13,
        MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12,
        MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11,
        MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10,
        MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9,
        MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8,
        MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7,
        MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6,
        MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5,
        MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4,
        MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3,
        MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2,
        MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1,
        MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0,
};

3、在arch/arm/mach-mx6/board-mx6q_xxxx.c中增加相关设备定义函数

static int mx6q_setup_weim_cs(void)

static int mx6q_setup_weim_cs(void)
{
        //nor
        void __iomem *ram_reg = MX6_IO_ADDRESS(WEIM_BASE_ADDR);//EIM memory base phy addr=0x21B8000
        void __iomem *ccm_reg = MX6_IO_ADDRESS(CCM_BASE_ADDR);
        unsigned int reg;
        struct clk *clk;
        u32 rate;
        /*iomuxc_gpr1 cs0 cs1 cs2 cs3 set*/
        //reg = readl(IOMUXC_GPR1);
        //printk("gpr1 reg=%x\n",reg); 
        /* CLKCTL_CCGR6: Set emi_slow_clock to be on in all modes */
        reg = readl(ccm_reg + 0x80);
        reg |= 0x00000C00;
        writel(reg, ccm_reg + 0x80);
        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);
        //printk("emi_slow_clk rate=%d\n",rate);
        if(rate!=132000000)
                printk(KERN_ERR "Warning: emi_slow_clk not set to 132 MHz!"
                                " WEIM NOR timing may be incorrect! rate %d \n", rate);
        //rate=clk_round_rate(clk,264000000);//37MHZ
        //clk_set_rate(clk,rate); 
        printk("emi_slow_clk rate=%d\n",rate);
        clk_put(clk);
    /*
       CS0GCR1: 
    GBC=0;CSREC=1;DSZ=2;BL=0;
       CREP=1;CSEN=1;
       Operation Mode: MUM=SRD=SWR=0.
       (Async write/Async page read,none multiplexed)
    */
        writel(0x00020081, ram_reg);//EIM_CS0GCR1 
    /*
       ADH=0
    */
        writel(0x00000000, ram_reg + 0x4); //EIM_CS0GCR2
    /*
    CS0RCR1:
       RWSC=1;//28
       RADVA=0;RADVN=0;
       OEA=0;OEN=0;
       RCSA=0;RCSN=0;
    */
        writel(0x01080000, ram_reg + 0x8);//EIM_CS0RCR1
    /*
    CS0RCR2:
       APR=1(Async Page Read);
       PAT=4(6 EIM clock syclks)
       changed RWSC=4,OEA=0,PAT=2;
    */
        writel(0x000000000, ram_reg + 0xc);//EIM_CS0RCR2
    /*
    CS0WCR1:
       WWSC=1;
       WADVA=0;WADVN=0;
       WBEA=0;WBEN=0;
       WEA=0;WEN=0;
       WCSA=0;WCSN=0;
    
    */
        writel(0x01000000, ram_reg + 0x10);//EIM_CS0WCR1 WWSC=3 EIM clk

    /*WBCDD=0*/

        writel(0x00000000, ram_reg + 0x14);
        writel(0x00000000, ram_reg + 0x090);
    //init pad

    mxc_iomux_v3_setup_multiple_pads(mx6q_weimram_pads,ARRAY_SIZE(mx6q_weimram_pads));
    //init pad
        printk("imx6q weim_cs0 init\n");
}

static struct eim_mxc_pdata eim_mxc

static struct eim_mxc_pdata eim_mxc = {
    .init = mx6q_setup_weim_cs,
};

static struct resource weim_fpga_resource

static struct resource weim_fpga_resource = {
        .start      = CS0_BASE_ADDR,
        .end        = CS0_BASE_ADDR  +  SZ_32M - 1,
        .flags      = IORESOURCE_MEM,
};

static struct platform_device weim_fpga_device

static struct platform_device weim_fpga_device = {
    .name          = "imx6q-fpga",
        .id            = -1,
        .num_resources = 1,
        .resource      = &weim_fpga_resource,
    .dev           = {
                .platform_data = &eim_mxc,
        }
};

4、在board_init(void)中进行设备注册

/* 2020.8.24add eim device*/
    platform_device_register(&weim_fpga_device);

5、重新编译生成内核

搞定;)

经FPGA测试,进行read、write时已能看见引脚时序逻辑,但是还不能正常读写到数据,估计是寄存器配置什么的问题,还要继续改进

后续解决方案见本人的另一篇博客

EIM总线驱动移植(二)_~~一道光的博客-CSDN博客_eim总线icon-default.png?t=M4ADhttps://blog.csdn.net/becdecorbin/article/details/108580017

本文仅是个人的学习记录,如有偏颇还请网友不吝赐教

imx6是NXP公司推出的款嵌入式处理器,EIM(External Interface Module)总线是它的种外部接口模块。EIM总线驱动是指在使用imx6处理器时,为了能够对EIM总线进行读写操作,需要通过驱动程序来控制该总线EIM总线驱动开发主要包括以下几个方面: 1. 硬件初始化:首先需要对imx6处理器的EIM总线进行初始化设置,包括时钟控制、引脚映射、中断配置等。 2. 寄存器操作:EIM总线的读写操作都需要通过对相应的寄存器进行读写来实现。驱动程序需要对这些寄存器进行正确的配置和操作,以实现对EIM总线的控制。 3. 数据传输:驱动程序需要实现数据在EIM总线上的传输。这包括数据的读取和写入,以及相应的时序控制和中断处理等操作。 4. 中断处理:当EIM总线发生中断时,驱动程序需要及时处理。这包括中断触发的条件判断、中断控制的设置和中断服务程序的编写等。 5. 错误处理:在使用EIM总线时可能会遇到些错误情况,如数据传输错误、中断处理错误等。驱动程序需要具备定的错误处理能力,以保证系统的正常运行和稳定性。 总之,imx6的EIM总线驱动是为了对该处理器上的EIM总线进行控制而开发种软件程序。它通过对硬件的初始化、对寄存器的操作、数据传输和中断处理等,实现了对EIM总线的控制和数据传输功能。这样就能够让开发人员在使用imx6处理器时,方便地进行对外部设备的读写操作。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值