Exynos 4412初始化外部地址总线
Exynos 4412外部地址总线与GPIO接口组Y(GPY)存在端口复用关系,其初始化需要操作以下寄存器:
- GPY0CON(0x11000000):配置片选脚(Xm0Csn)和读/写选通脚(EBI_OEn/EBI_WEn)功能复用。
- GPY0PUD(0x11000128):配置片选脚(Xm0Csn)和读/写选通脚(EBI_OEn/EBI_WEn)上下拉。
- GPY1CON(0x11000140):配置数据就绪脚(EBI_DATA_RDn)、WAIT信号输入脚(SROM_WAITn)、字节模式操作选通脚(EBI_BEn)功能复用。
- GPY1PUD(0x11000148):配置数据就绪脚(EBI_DATA_RDn)、WAIT信号输入脚(SROM_WAITn)、字节模式操作选通脚(EBI_BEn)上下拉。
- GPY2CON(0x11000160):配置NAND Flash相关脚功能复用。
- GPY2PUD(0x11000168):配置NAND Flash相关脚上下拉。
- GPY3CON(0x11000180):配置低位地址线(ADDR[0..7])脚功能复用。
- GPY3PUD(0x11000188):配置低位地址线(ADDR[0..7])脚脚上下拉。
- GPY4CON(0x110001A0):配置高位地址线(ADDR[8..15])脚脚功能复用。
- GPY4PUD(0x110001A8):配置高位地址线(ADDR[8..15])脚脚上下拉。
- GPY5CON(0x110001C0):配置低位数据线(DATA[0..7])脚功能复用。
- GPY5PUD(0x110001C8):配置低位数据线(DATA[0..7])脚上下拉。
- GPY6CON(0x110001E0):配置高位数据线(DATA[8..15])脚功能复用。
- GPY6PUD(0x110001E8):配置高位数据线(DATA[8..15])脚上下拉。
ARM汇编代码
例中,外部设备的片选脚位于Xm0Cs1(GPY0_1),模式为SROM。
参考自https://blog.csdn.net/u011583798/article/details/70215739
/* CSn, WE, OE*/
ldr r0, =0x11000120 //GPY0CON
ldr r1, =0x00222222 //SROM_CSn, EBI_OEn, EBI_WEn
str r1, [r0]
/* BE, WAIT, RD */
ldr r0, =0x11000140 //GPY1CON
ldr r1, =0x00002222 //EBI
str r1, [r0]
/* ADDR[0-7], pull up */
ldr r0, =0x11000180 //GPY3CON
ldr r1, =0x22222222 //EBI_ADDR
str r1, [r0]
ldr r0, =0x11000188 //GPY3PUD
ldr r1, =0x0000FFFF //PULL_UP
str r1, [r0]
/* DATA[0-7], pull up */
ldr r0, =0x110001C0 //GPY5CON
ldr r1, =0x22222222 //EBI_DATA
str r1, [r0]
ldr r0, =0x110001C8 //GPY5PUD
ldr r1, =0x0000FFFF //PULL_UP
str r1, [r0]
/* DATA[8-15], pull up */
ldr r0, =0x110001E0 //GPY6CON
ldr r1, =0x22222222 //EBI_DATA
str r1, [r0]
ldr r0, =0x110001E8 //GPY6PUD
ldr r1, =0x0000FFFF //PULL_UP
str r1, [r0]
/* SROM BANK 1 */
ldr r0, =0x12570000 //SROM_BW
ldr r1, [r0]
orr r1, r1, #0xF0 //视情况改变SROM_BW寄存器的值
str r1, [r0]
ldr r0, =0x12570008 //SROM_BC1
ldr r1, =SROM_BC1_VAL //视情况改变SROM_BCn寄存器的值
str r1, [r0]
C代码
例中,外部设备的片选脚位于Xm0Cs1(GPY0_1),模式为SROM。
/* PLATFORM SUPPORT :: SROM ACCESS :: SAMSUNG :: EXYNOS 4412 * * This header file contains code that used to configure Samsung Exynos 4412 SoC's External Bus Interface (EBI) for SROM access. * Including register configurations and GPIO pin configurations. * * GPIO constants and functions are defined in the following location(s) in iTop-4412's Linux Kernel source: * - arch\arm\plat-samsung\include\plat\gpio-cfg.h * */ #ifndef _PLATFORMSUPPORT_SROMACCESS_SAMSUNG_EXYNOS4412_H #define _PLATFORMSUPPORT_SROMACCESS_SAMSUNG_EXYNOS4412_H /* Main header files */ #include <linux/init.h> #include <linux/module.h> /* Useful header files */ #include <linux/kernel.h> #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/delay.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/uaccess.h> #include <asm/io.h> /* Interrupt-related header files */ #include <linux/interrupt.h> #include <linux/irq.h> /* Library to generate random numbers */ #include <linux/random.h> /* Spin-Lock, for we need it in Interrupt Handlers, we can't use Mutex */ #include <linux/spinlock.h> /* Timers */ #include <linux/timer.h> #include <linux/jiffies.h> /* Platform-related header files */ #include <mach/gpio.h> #include <mach/regs-gpio.h> #include <plat/gpio-cfg.h> /* Local header files */ #include "ultsnddrv4412.h" #include "MathFunctions.h" /* Defines that EBI configurations are requested */ #define EBI_CONFIG_REQUESTED /* External Bus Interface (EBI) Configurations */ #define CHIP_SELECT_GPIO_LABEL EXYNOS4_GPY0(1) //Chip Select pin label #define CHIP_SELECT_GPIO_NAME "CHIP_SELECT_XM0CS1" //Chip Select pin name //EBI Related GPIOs #define EBI_WEN_GPIO_LABEL EXYNOS4_GPY0(5) //nWE pin label #define EBI_OEN_GPIO_LABEL EXYNOS4_GPY0(4) //nOE pin label #define EBI_GPY1CON_START EXYNOS4_GPY1(0) //GPY1CON start #define EBI_GPY1CON_END EXYNOS4_GPY1(3) //GPY1CON end #define EBI_GPY1CON_PINCOUNT 4 //Pin count #define EBI_ADDRLOW_START EXYNOS4_GPY3(0) //GPY3CON start (ADDR[0..7]) #define EBI_ADDRLOW_END EXYNOS4_GPY3(7) //GPY3CON end #define EBI_ADDRLOW_PINCOUNT 8 //Pin count #define EBI_ADDRHIGH_START EXYNOS4_GPY4(0) //GPY3CON start (ADDR[8..15]) #define EBI_ADDRHIGH_END EXYNOS4_GPY4(7) //GPY3CON end #define EBI_ADDRHIGH_PINCOUNT 8 //Pin count #define EBI_DATALOW_START EXYNOS4_GPY5(0) //GPY5CON start (DATA[0..7]) #define EBI_DATALOW_END EXYNOS4_GPY5(7) //GPY5CON end #define EBI_DATALOW_PINCOUNT 8 //Pin count #define EBI_DATAHIGH_START EXYNOS4_GPY6(0) //GPY6CON start (DATA[8..15]) #define EBI_DATAHIGH_END EXYNOS4_GPY6(7) //GPY6CON end #define EBI_DATAHIGH_PINCOUNT 8 //Pin count //SROM_BXx Registers #define S3C_REGISTER_SROM_BASE_ADDR 0x12570000 //Base address of register "SROM_BW" and "SROM_BCn", we will reconfigure SROM_BW[4..7] and SROM_BC1[31..0] #define S3C_REGISTER_SROM_SIZE_BYTE 0x20 //Size of SROM_BW and SROM_BCn, 4 Bytes (32Bit) x 5 #define S3C_REGISTER_SROM_NAME "SROM_BXx" //Name of requested memory region #define S3C_REGISTER_SROM_BW_ADDR_OFFSET 0x00 //Address offset of SROM_BW #define S3C_REGISTER_SROM_BC0_ADDR_OFFSET 0x04 //Address offset of SROM_BC0 #define S3C_REGISTER_SROM_BC1_ADDR_OFFSET 0x08 //Address offset of SROM_BC1 #define S3C_REGISTER_SROM_BC2_ADDR_OFFSET 0x0C //Address offset of SROM_BC2 #define S3C_REGISTER_SROM_BC3_ADDR_OFFSET 0x10 //Address offset of SROM_BC3 #define S3C_REGISTER_SROM_BW_CONFIG_BITS 0x00000010 //Set SROM_BW[4..7] to binary value 0001 (Does not use UB/LB, Disables WAIT, Half-word base address, 16bit data bus width). SROM_BW=SROM_BW | S3C_REGISTER_SROM_BW_CONFIG_BITS #define S3C_REGISTER_SROM_BC1_CONFIG_BITS 0x000F0000 //Use short-timed reading timing for restructured FPGA, Tacs=0, Tcos=0, Tacc=16, Tcoh=0, Tcah=0, Tacp=0 (Cycles, 1 Cycle = 5 ns). SROM_BC1=SROM_BC1 | S3C_REGISTER_SROM_BC1_CONFIG_BITS //#define S3C_REGISTER_SROM_BC1_CONFIG_BITS 0xFF1FFF00 //Use long-timed reading timing for original FPGA, Tacs=15, Tcos=15, Tacc=32, Tcoh=15, Tcah=15, Tacp=0 (Cycles, 1 Cycle = 5 ns). SROM_BC1=SROM_BC1 | S3C_REGISTER_SROM_BC1_CONFIG_BITS /* Address of SROM_BW and SROM_BC1 */ static void * lpSromRegistersBaseAddress = NULL; //Remapped address for SROM_BW static struct resource * lpSromRegistersResource = NULL; //Memory region resource static unsigned int iSromBw; //Value of SROM_BW static unsigned int iSromBc1; //Value of SROM_BC1 /* Configure SROM access on initializing */ //Returns 0 if operation is success static int InitConfigureSROMAccess(){ //Config SROM_BXx Registers request_region(S3C_REGISTER_SROM_BASE_ADDR, S3C_REGISTER_SROM_SIZE_BYTE, S3C_REGISTER_SROM_NAME); lpSromRegistersBaseAddress = ioremap(S3C_REGISTER_SROM_BASE_ADDR, S3C_REGISTER_SROM_SIZE_BYTE); lpSromRegistersResource = request_mem_region(S3C_REGISTER_SROM_BASE_ADDR, S3C_REGISTER_SROM_SIZE_BYTE, S3C_REGISTER_SROM_NAME); if (lpSromRegistersBaseAddress){ NFOPRINT("SFR SROM_BW and SROM_BCn mapped to virtual address 0x%x.\n", lpSromRegistersBaseAddress); iSromBw=__raw_readl(lpSromRegistersBaseAddress); DBGPRINT("SFR SROM_BW=0x%x.\n", iSromBw); iSromBw=iSromBw | S3C_REGISTER_SROM_BW_CONFIG_BITS; DBGPRINT("Writing SROM_BW with 0x%x inorder to config Xm0Cs1.\n", iSromBw); __raw_writel(iSromBw, lpSromRegistersBaseAddress); iSromBw=__raw_readl(lpSromRegistersBaseAddress); DBGPRINT("SFR SROM_BW=0x%x.\n", iSromBw); iSromBc1=__raw_readl(lpSromRegistersBaseAddress + S3C_REGISTER_SROM_BC1_ADDR_OFFSET); DBGPRINT("SFR SROM_BC1=0x%x.\n", iSromBc1); iSromBc1=iSromBc1 | S3C_REGISTER_SROM_BC1_CONFIG_BITS; DBGPRINT("Writing SROM_BC1 with 0x%x inorder to config Xm0Cs1.\n", iSromBc1); __raw_writel(iSromBc1, lpSromRegistersBaseAddress + S3C_REGISTER_SROM_BC1_ADDR_OFFSET); iSromBc1=__raw_readl(lpSromRegistersBaseAddress + S3C_REGISTER_SROM_BC1_ADDR_OFFSET); DBGPRINT("SFR SROM_BC1=0x%x.\n", iSromBc1); } else{ WRNPRINT("Failed to map SFR SROM_BW and SROM_BCn. The remap of external device at Xm0Cs1 may not success.\n"); } //Request GPIOs for external device mapping int iCsResult=0; iCsResult=gpio_request(CHIP_SELECT_GPIO_LABEL, CHIP_SELECT_GPIO_NAME); if (0==iCsResult){ //Config EBI int iEBIConfigResult=0; //GPY0 iEBIConfigResult=s3c_gpio_cfgpin(CHIP_SELECT_GPIO_LABEL, S3C_GPIO_SFN(0x2)); //Set GPY0CON[1] to 0x2 (SROM_CSn[1]) if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY0_1 (Xm0Cs1), Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } s3c_gpio_setpull(CHIP_SELECT_GPIO_LABEL, S3C_GPIO_PULL_UP); //Set GPY0PUD[1] to PULL_UP s5p_gpio_set_drvstr(CHIP_SELECT_GPIO_LABEL, S5P_GPIO_DRVSTR_LV4); //Set drive strength to max iEBIConfigResult=s3c_gpio_cfgpin(EBI_WEN_GPIO_LABEL, S3C_GPIO_SFN(0x2)); //Set GPY0CON[5] to 0x2 (EBI_WEn) if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY0_5 (Xm0WEn), Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } s3c_gpio_setpull(EBI_WEN_GPIO_LABEL, S3C_GPIO_PULL_UP); //Set GPY0PUD[5] to PULL_UP iEBIConfigResult=s3c_gpio_cfgpin(EBI_OEN_GPIO_LABEL, S3C_GPIO_SFN(0x2)); //Set GPY0CON[4] to 0x2 (EBI_OEn) if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY0_4 (Xm0OEn), Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } s3c_gpio_setpull(EBI_OEN_GPIO_LABEL, S3C_GPIO_PULL_UP); //Set GPY0PUD[4] to PULL_UP //GPY1 iEBIConfigResult=s3c_gpio_cfgall_range(EBI_GPY1CON_START, EBI_GPY1CON_PINCOUNT, S3C_GPIO_SFN(0x2), S3C_GPIO_PULL_UP); //Set GPY1CON to 0x00002222 (EBI_DATA_RDn, SROM_WAITn, EBI_BEn[1], EBI_BEn[0]) if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY1, Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } //ADDR s3c_gpio_cfgall_range(EBI_ADDRLOW_START, EBI_ADDRLOW_PINCOUNT, S3C_GPIO_SFN(0x2), S3C_GPIO_PULL_UP); //set GPY3CON to 0x22222222 (EBI_ADDR[7..0]), and set GPY3PUD to 0x0000FFFF (PULL_UP) if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY3 (Xm0ADDR[0..7]), Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } //s3c_gpio_cfgall_range(EBI_ADDRHIGH_START, EBI_ADDRHIGH_PINCOUNT, S3C_GPIO_SFN(0x2), S3C_GPIO_PULL_UP); //set GPY4CON to 0x22222222 (EBI_ADDR[15..8]), and set GPY4PUD to 0x0000FFFF (PULL_UP) //if (iEBIConfigResult != 0){ // WRNPRINT("Failed to config GPY4 (Xm0ADDR[8..15]), Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); //} //DATA s3c_gpio_cfgall_range(EBI_DATALOW_START, EBI_DATALOW_PINCOUNT, S3C_GPIO_SFN(0x2), S3C_GPIO_PULL_UP); if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY5 (Xm0DATA[0..7]), Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } s3c_gpio_cfgall_range(EBI_DATAHIGH_START, EBI_DATAHIGH_PINCOUNT, S3C_GPIO_SFN(0x2), S3C_GPIO_PULL_UP); //Set GPY5CON & GPY6CON to 0x22222222 (EBI_DATA), and set GPY5PUD & GPY6PUD to 0x0000FFFF (PULL_UP) if (iEBIConfigResult != 0){ WRNPRINT("Failed to config GPY6, Error %d. The remap of external device at Xm0Cs1 may not success.\n", iEBIConfigResult); } gpio_free(CHIP_SELECT_GPIO_LABEL); return 0; } else{ WRNPRINT("Request GPIO %d failed with return code %d. Unnable to remap external device.\n", CHIP_SELECT_GPIO_LABEL, iCsResult); return iCsResult; } } /* Release SROM access on initializing */ static void ExitReleaseSROMAccess(){ iounmap(lpSromRegistersBaseAddress); release_mem_region(lpSromRegistersResource, S3C_REGISTER_SROM_SIZE_BYTE); release_region(S3C_REGISTER_SROM_BASE_ADDR, S3C_REGISTER_SROM_SIZE_BYTE); return; } #endif
页面版本: 5, 最后编辑于: 06 Apr 2022 03:51