#include "chip.h" #include "rdc.h" #define DDR_RDC_MEM_RANGE (512*1024*1024) #define SRAM_RDC_MEM_RANGE (4*1024*1024) // CRTL #define SEC_CFG_LOCK (1<<31) #define INC_BLK_IDX (1<<8) typedef struct { rdc_master_e master; uint32_t seg_start; uint32_t seg_end; uint8_t access; // 0: not allow access 1: allow access }rdc_init_item_t; // seg size = 1MB static const rdc_init_item_t rdc_ddr_init_tab[] = { {RDC_M_CPU, 0, 512, 1}, {RDC_M_MCU, 0, 512, 1}, {RDC_M_LCD, 0, 512, 1}, {RDC_M_ITU, 0, 512, 1}, {RDC_M_MFC, 0, 512, 1}, {RDC_M_GPU, 0, 512, 1}, {RDC_M_QOI, 0, 512, 1}, {RDC_M_BLEND, 0, 512, 1}, {RDC_M_PXP, 0, 512, 1}, {RDC_M_WRAP, 0, 512, 1}, {RDC_M_DMA, 0, 512, 1}, {RDC_M_USB, 0, 512, 1}, {RDC_M_SD0, 0, 512, 1}, {RDC_M_SD1, 0, 512, 1}, {RDC_M_ETH, 0, 512, 1}, }; // seg size = 128KB static const rdc_init_item_t rdc_sram_init_tab[] = { {RDC_M_CPU, 0, 32, 1}, {RDC_M_MCU, 0, 32, 1}, {RDC_M_LCD, 0, 32, 1}, {RDC_M_ITU, 0, 32, 1}, {RDC_M_MFC, 0, 32, 1}, {RDC_M_GPU, 0, 32, 1}, {RDC_M_QOI, 0, 32, 1}, {RDC_M_BLEND, 0, 32, 1}, {RDC_M_PXP, 0, 32, 1}, {RDC_M_WRAP, 0, 32, 1}, {RDC_M_DMA, 0, 32, 1}, {RDC_M_USB, 0, 32, 1}, {RDC_M_SD0, 0, 32, 1}, {RDC_M_SD1, 0, 32, 1}, {RDC_M_ETH, 0, 32, 1}, }; /* * When set to 1, CTRL, BLK_LUT, IRQ_ENABLE and IRQ_SET become read-only registers. * To set this bit to 0, the RDC must be reset. */ static void rdc_ddr_security_cfg_lock(rdc_ddr_t *rdc, int lock) { if (lock) rdc->CTRL |= SEC_CFG_LOCK; else rdc->CTRL &= ~SEC_CFG_LOCK; } static void rdc_ddr_blk_idx_auto_inc_enable(rdc_ddr_t *rdc, int enable) { if (enable) rdc->CTRL |= INC_BLK_IDX; else rdc->CTRL &= ~INC_BLK_IDX; } static uint32_t rdc_ddr_get_blk_max(rdc_ddr_t *rdc) { if (rdc->BLK_MAX == 0) return 1; else return rdc->BLK_MAX; } static uint32_t rdc_ddr_get_blk_size_in_bytes(rdc_ddr_t *rdc) { return DDR_RDC_MEM_RANGE / rdc_ddr_get_blk_max(rdc); } static int rdc_ddr_set_blk_idx(rdc_ddr_t *rdc, uint32_t blk) { if (blk >= rdc_ddr_get_blk_max(rdc)) return -1; rdc->BLK_IDX_ADDR = blk; return 0; } static uint32_t rdc_ddr_get_seg_max_of_blk(rdc_ddr_t *rdc) { return 32; } static uint32_t rdc_ddr_get_seg_sum(rdc_ddr_t *rdc) { return rdc_ddr_get_seg_max_of_blk(rdc) * rdc_ddr_get_blk_max(rdc); } static uint32_t rdc_ddr_get_seg_size_in_bytes(rdc_ddr_t *rdc) { return DDR_RDC_MEM_RANGE / rdc_ddr_get_seg_sum(rdc); } /* *@param * access: * 0: not allow access 1: allow access */ static int rdc_ddr_set_seg_range_of_blk(rdc_ddr_t *rdc, uint32_t blk, uint32_t seg_start, uint32_t seg_end, uint8_t access) { if (seg_start >= rdc_ddr_get_seg_max_of_blk(rdc)) return -1; if (seg_end > rdc_ddr_get_seg_max_of_blk(rdc)) return -1; if (seg_start >= seg_end) return -1; if (rdc_ddr_set_blk_idx(rdc, blk) != 0) return -1; if (access) { rdc->BLK_LUT &= ~((~(0xffffffff << (seg_end - seg_start))) << seg_start); } else { rdc->BLK_LUT |= ((~(0xffffffff << (seg_end - seg_start))) << seg_start); } return 0; } static uint32_t rdc_ddr_get_irq_status(rdc_ddr_t *rdc) { return rdc->IRQ_STAT; } static void rdc_ddr_irq_enable(rdc_ddr_t *rdc, uint32_t irqs, int enable) { if (enable) rdc->IRQ_ENABLE |= irqs; else rdc->IRQ_ENABLE &= ~irqs; } static void rdc_ddr_irq_clear(rdc_ddr_t *rdc, uint32_t irqs) { rdc->IRQ_CLEAR |= irqs; } /* * used for debug. */ static void rdc_ddr_irq_set(rdc_ddr_t *rdc, uint32_t irqs, int set) { if (set) rdc->IRQ_SET |= irqs; else rdc->IRQ_SET &= ~irqs; } /* *@param * access: * 0: not allow access 1: allow access *@note: * seg size = 1 MB. * seg max = 512. */ int rdc_ddr_set_master_mem_range(rdc_ddr_t *rdc, rdc_master_e rdc_master, uint32_t seg_start, uint32_t seg_end, uint8_t access) { int blk_start; int blk_end; int i; int seg_start_of_blk; int seg_end_of_blk; if (seg_start >= rdc_ddr_get_seg_sum(rdc)) return -1; if (seg_end > rdc_ddr_get_seg_sum(rdc)) return -1; if (seg_start >= seg_end) return -1; rdc_ddr_blk_idx_auto_inc_enable(rdc, 0); blk_start = seg_start / rdc_ddr_get_seg_max_of_blk(rdc); blk_end = (seg_end + rdc_ddr_get_seg_max_of_blk(rdc) - 1) / rdc_ddr_get_seg_max_of_blk(rdc); for (i=blk_start; i (seg_end - seg_start)) { seg_end_of_blk = seg_start_of_blk + seg_end - seg_start; } else { seg_end_of_blk = rdc_ddr_get_seg_max_of_blk(rdc); } seg_start += seg_end_of_blk - seg_start_of_blk; rdc->LUT_MASTER_SEL = rdc_master; rdc_ddr_set_seg_range_of_blk(rdc, i, seg_start_of_blk, seg_end_of_blk, access); } return 0; } /* *@brief: * 获取从seg_offset开始的第一段符合access条件的段区域。 */ int rdc_ddr_get_master_mem_range(rdc_ddr_t *rdc, rdc_master_e rdc_master, uint32_t seg_offset, uint32_t *seg_start, uint32_t *seg_end, uint8_t access) { int ret = -1; int blk; int seg; int flag = 0; if (seg_offset >= rdc_ddr_get_seg_sum(rdc)) { goto exit; } rdc_ddr_blk_idx_auto_inc_enable(rdc, 0); rdc->LUT_MASTER_SEL = rdc_master; blk = seg_offset / rdc_ddr_get_seg_max_of_blk(rdc); seg = seg_offset % rdc_ddr_get_seg_max_of_blk(rdc); for (; blkBLK_LUT & (1 << seg))) { if (!flag) { flag = 1; *seg_end = rdc_ddr_get_seg_sum(rdc); *seg_start = blk*rdc_ddr_get_seg_max_of_blk(rdc) + seg; } } else { if (flag) { *seg_end = blk*rdc_ddr_get_seg_max_of_blk(rdc) + seg; ret = 0; goto exit; } } } else { if (rdc->BLK_LUT & (1 << seg)) { if (!flag) { flag = 1; *seg_end = rdc_ddr_get_seg_sum(rdc); *seg_start = blk*rdc_ddr_get_seg_max_of_blk(rdc) + seg; } } else { if (flag) { *seg_end = blk*rdc_ddr_get_seg_max_of_blk(rdc) + seg; ret = 0; goto exit; } } } } seg = 0; } exit: return ret; } /* *@brief: * 获取master在某段上的访问权限。 *@return: * 0: 不允许访问 1: 允许访问 */ int rdc_ddr_get_master_mem_seg_access_sta(rdc_ddr_t *rdc, rdc_master_e rdc_master, uint32_t seg) { int blk; if (seg >= rdc_ddr_get_seg_sum(rdc)) { return 0; } rdc_ddr_blk_idx_auto_inc_enable(rdc, 0); rdc->LUT_MASTER_SEL = rdc_master; blk = seg / rdc_ddr_get_seg_max_of_blk(rdc); rdc_ddr_set_blk_idx(rdc, blk); seg = seg % rdc_ddr_get_seg_max_of_blk(rdc); return (rdc->BLK_LUT & (1 << seg))? 0:1; } static rdc_irq_info_t rdc_ddr_get_irq_info_vbus(rdc_ddr_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_VBUS; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_VBUS & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_VBUS & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_VBUS & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_VBUS & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_VBUS & 0xffff; return bus_irq_info; } static rdc_irq_info_t rdc_ddr_get_irq_info_gbus(rdc_ddr_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_GBUS; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_GBUS & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_GBUS & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_GBUS & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_GBUS & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_GBUS & 0xffff; return bus_irq_info; } static rdc_irq_info_t rdc_ddr_get_irq_info_chbus(rdc_ddr_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_CHBUS; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_CHBUS & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_CHBUS & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_CHBUS & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_CHBUS & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_CHBUS & 0xffff; return bus_irq_info; } static rdc_irq_info_t rdc_ddr_get_irq_info_mcu(rdc_ddr_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_MCU; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_MCU & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_MCU & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_MCU & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_MCU & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_MCU & 0xffff; return bus_irq_info; } static rdc_irq_info_t rdc_ddr_get_irq_info_cpu(rdc_ddr_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_CPU; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_CPU & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_CPU & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_CPU & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_CPU & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_CPU & 0xffff; return bus_irq_info; } static void rdc_sram_security_cfg_lock(rdc_sram_t *rdc, int lock) { if (lock) rdc->CTRL |= SEC_CFG_LOCK; else rdc->CTRL &= ~SEC_CFG_LOCK; } static void rdc_sram_blk_idx_auto_inc_enable(rdc_sram_t *rdc, int enable) { if (enable) rdc->CTRL |= INC_BLK_IDX; else rdc->CTRL &= ~INC_BLK_IDX; } static uint32_t rdc_sram_get_blk_max(rdc_sram_t *rdc) { return 1; } static uint32_t rdc_sram_get_blk_size_in_bytes(rdc_sram_t *rdc) { return SRAM_RDC_MEM_RANGE / rdc_sram_get_blk_max(rdc); } static int rdc_sram_set_blk_idx(rdc_sram_t *rdc, uint32_t blk) { return 0; } static uint32_t rdc_sram_get_seg_max_of_blk(rdc_sram_t *rdc) { return 32; } static uint32_t rdc_sram_get_seg_sum(rdc_sram_t *rdc) { return rdc_sram_get_seg_max_of_blk(rdc) * rdc_sram_get_blk_max(rdc); } static uint32_t rdc_sram_get_seg_size_in_bytes(rdc_sram_t *rdc) { return SRAM_RDC_MEM_RANGE / rdc_sram_get_seg_sum(rdc); } /* *@param * access: * 0: not allow access 1: allow access */ static int rdc_sram_set_seg_range_of_blk(rdc_sram_t *rdc, uint32_t blk, uint32_t seg_start, uint32_t seg_end, uint8_t access) { if (seg_start >= rdc_sram_get_seg_max_of_blk(rdc)) return -1; if (seg_end > rdc_sram_get_seg_max_of_blk(rdc)) return -1; if (seg_start >= seg_end) return -1; if (rdc_sram_set_blk_idx(rdc, blk) != 0) return -1; if (access) { rdc->BLK_LUT &= ~((~(0xffffffff << (seg_end - seg_start))) << seg_start); } else { rdc->BLK_LUT |= ((~(0xffffffff << (seg_end - seg_start))) << seg_start); } return 0; } static uint32_t rdc_sram_get_irq_status(rdc_sram_t *rdc) { return rdc->IRQ_STAT; } static void rdc_sram_irq_enable(rdc_sram_t *rdc, uint32_t irqs, int enable) { if (enable) rdc->IRQ_ENABLE |= irqs; else rdc->IRQ_ENABLE &= ~irqs; } static void rdc_sram_irq_clear(rdc_sram_t *rdc, uint32_t irqs) { rdc->IRQ_CLEAR |= irqs; } static void rdc_sram_irq_set(rdc_sram_t *rdc, uint32_t irqs, int set) { if (set) rdc->IRQ_SET |= irqs; else rdc->IRQ_SET &= ~irqs; } /* *@brief: * 获取从seg_offset开始的第一段符合access条件的段区域。 */ int rdc_sram_get_master_mem_range(rdc_sram_t *rdc, rdc_master_e rdc_master, uint32_t seg_offset, uint32_t *seg_start, uint32_t *seg_end, uint8_t access) { int ret = -1; int blk; int seg; int flag = 0; if (seg_offset >= rdc_sram_get_seg_sum(rdc)) { goto exit; } rdc_sram_blk_idx_auto_inc_enable(rdc, 0); rdc->LUT_MASTER_SEL = rdc_master; blk = seg_offset / rdc_sram_get_seg_max_of_blk(rdc); seg = seg_offset % rdc_sram_get_seg_max_of_blk(rdc); for (; blkBLK_LUT & (1 << seg))) { if (!flag) { flag = 1; *seg_end = rdc_sram_get_seg_sum(rdc); *seg_start = blk*rdc_sram_get_seg_max_of_blk(rdc) + seg; } } else { if (flag) { *seg_end = blk*rdc_sram_get_seg_max_of_blk(rdc) + seg; ret = 0; goto exit; } } } else { if (rdc->BLK_LUT & (1 << seg)) { if (!flag) { flag = 1; *seg_end = rdc_sram_get_seg_sum(rdc); *seg_start = blk*rdc_sram_get_seg_max_of_blk(rdc) + seg; } } else { if (flag) { *seg_end = blk*rdc_sram_get_seg_max_of_blk(rdc) + seg; ret = 0; goto exit; } } } } seg = 0; } exit: return ret; } /* *@brief: * 获取master在某段上的访问权限。 *@return: * 0: 不允许访问 1: 允许访问 */ int rdc_sram_get_master_mem_seg_access_sta(rdc_sram_t *rdc, rdc_master_e rdc_master, uint32_t seg) { int blk; if (seg >= rdc_sram_get_seg_sum(rdc)) { return 0; } rdc_sram_blk_idx_auto_inc_enable(rdc, 0); rdc->LUT_MASTER_SEL = rdc_master; blk = seg / rdc_sram_get_seg_max_of_blk(rdc); rdc_sram_set_blk_idx(rdc, blk); seg = seg % rdc_sram_get_seg_max_of_blk(rdc); return (rdc->BLK_LUT & (1 << seg))? 0:1; } /* *@param * access: * 0: not allow access 1: allow access *@note: * seg size = 128 KB. * seg max = 32. */ int rdc_sram_set_master_mem_range(rdc_sram_t *rdc, rdc_master_e rdc_master, uint32_t seg_start, uint32_t seg_end, uint8_t access) { int blk_start; int blk_end; int i; int seg_start_of_blk; int seg_end_of_blk; if (seg_start >= rdc_sram_get_seg_sum(rdc)) return -1; if (seg_end > rdc_sram_get_seg_sum(rdc)) return -1; if (seg_start >= seg_end) return -1; rdc_sram_blk_idx_auto_inc_enable(rdc, 0); blk_start = seg_start / rdc_sram_get_seg_max_of_blk(rdc); blk_end = (seg_end + rdc_sram_get_seg_max_of_blk(rdc) - 1) / rdc_sram_get_seg_max_of_blk(rdc); for (i=blk_start; i (seg_end - seg_start)) { seg_end_of_blk = seg_start_of_blk + seg_end - seg_start; } else { seg_end_of_blk = rdc_sram_get_seg_max_of_blk(rdc); } seg_start += seg_end_of_blk - seg_start_of_blk; rdc->LUT_MASTER_SEL = rdc_master; rdc_sram_set_seg_range_of_blk(rdc, i, seg_start_of_blk, seg_end_of_blk, access); } return 0; } static rdc_irq_info_t rdc_sram_get_irq_info_others(rdc_sram_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_OTHERS; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_OTHERS & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_OTHERS & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_OTHERS & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_OTHERS & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_OTHERS & 0xffff; return bus_irq_info; } static rdc_irq_info_t rdc_sram_get_irq_info_mcu(rdc_sram_t *rdc) { rdc_irq_info_t bus_irq_info = {0}; bus_irq_info.violation_addr = rdc->IRQ_INFO1_MCU; bus_irq_info.AxPROT = (rdc->IRQ_INFO2_MCU & (1<<31))? 1:0; bus_irq_info.ERR_MULTI = (rdc->IRQ_INFO2_MCU & (1<<24))? 1:0; bus_irq_info.ERR_BOTH = (rdc->IRQ_INFO2_MCU & (1<<20))? 1:0; bus_irq_info.WnR = (rdc->IRQ_INFO2_MCU & (1<<16))? 1:0; bus_irq_info.AxID = rdc->IRQ_INFO2_MCU & 0xffff; return bus_irq_info; } static void print_irq_info(rdc_irq_info_t irq_info) { #if 1 printf("ADDR:0x%x\r\n \ AxPROT:%d\r\n \ ERR_MULTI:%d\r\n \ ERR_BOTH:%d\r\n \ WnR:%d\r\n \ AxID:0x%x\r\n", irq_info.violation_addr, irq_info.AxPROT, irq_info.ERR_MULTI, irq_info.ERR_BOTH, irq_info.WnR, irq_info.AxID); #endif } static void rdc_ddr_IrqHandler(void *param) { uint32_t irq_sta; rdc_irq_info_t irq_info; rdc_ddr_t *rdc = (rdc_ddr_t *)param; irq_sta = rdc_ddr_get_irq_status(rdc); if (irq_sta & RDC_DDR_IRQ_CPU) { rdc_ddr_irq_set(rdc, RDC_DDR_IRQ_CPU, 0); irq_info = rdc_ddr_get_irq_info_cpu(rdc); printf("[rdc] ddr error int from CPU!\r\n"); print_irq_info(irq_info); } if (irq_sta & RDC_DDR_IRQ_MCU) { rdc_ddr_irq_set(rdc, RDC_DDR_IRQ_MCU, 0); irq_info = rdc_ddr_get_irq_info_mcu(rdc); printf("[rdc] ddr error int from MCU!\r\n"); print_irq_info(irq_info); } if (irq_sta & RDC_DDR_IRQ_CHBUS) { rdc_ddr_irq_set(rdc, RDC_DDR_IRQ_CHBUS, 0); irq_info = rdc_ddr_get_irq_info_chbus(rdc); printf("[rdc] ddr error int from CHBUS!\r\n"); print_irq_info(irq_info); } if (irq_sta & RDC_DDR_IRQ_GBUS) { rdc_ddr_irq_set(rdc, RDC_DDR_IRQ_GBUS, 0); irq_info = rdc_ddr_get_irq_info_gbus(rdc); printf("[rdc] ddr error int from GBUS!\r\n"); print_irq_info(irq_info); } if (irq_sta & RDC_DDR_IRQ_VBUS) { rdc_ddr_irq_set(rdc, RDC_DDR_IRQ_VBUS, 0); irq_info = rdc_ddr_get_irq_info_vbus(rdc); printf("[rdc] ddr error int from VBUS!\r\n"); print_irq_info(irq_info); } rdc_ddr_irq_clear(rdc ,irq_sta); } static void rdc_sram_IrqHandler(void *param) { uint32_t irq_sta; rdc_irq_info_t irq_info; rdc_sram_t *rdc = (rdc_sram_t *)param; irq_sta = rdc_sram_get_irq_status(rdc); if (irq_sta & RDC_SRAM_IRQ_MCU) { rdc_sram_irq_set(rdc, RDC_SRAM_IRQ_MCU, 0); irq_info = rdc_sram_get_irq_info_mcu(rdc); printf("[rdc] sram error int from MCU!\r\n"); print_irq_info(irq_info); } if (irq_sta & RDC_SRAM_IRQ_OTHER) { rdc_sram_irq_set(rdc, RDC_SRAM_IRQ_OTHER, 0); irq_info = rdc_sram_get_irq_info_others(rdc); printf("[rdc] sram error int from others!\r\n"); print_irq_info(irq_info); } rdc_sram_irq_clear(rdc ,irq_sta); } static void rdc_ddr_init(rdc_ddr_t *rdc) { int i; for (i=0; i< sizeof(rdc_ddr_init_tab)/sizeof(rdc_ddr_init_tab[0]); i++) { rdc_ddr_set_master_mem_range(rdc, rdc_ddr_init_tab[i].master, rdc_ddr_init_tab[i].seg_start, rdc_ddr_init_tab[i].seg_end, rdc_ddr_init_tab[i].access); } request_irq(RDC_DDR_IRQn, 0, rdc_ddr_IrqHandler, (void *)rdc); rdc_ddr_irq_enable(rdc, RDC_DDR_IRQ_CPU | RDC_DDR_IRQ_MCU | \ RDC_DDR_IRQ_CHBUS | RDC_DDR_IRQ_GBUS | \ RDC_DDR_IRQ_VBUS, 1); } static void rdc_sram_init(rdc_sram_t *rdc) { int i; for (i=0; i< sizeof(rdc_sram_init_tab)/sizeof(rdc_sram_init_tab[0]); i++) { rdc_sram_set_master_mem_range(rdc, rdc_sram_init_tab[i].master, rdc_sram_init_tab[i].seg_start, rdc_sram_init_tab[i].seg_end, rdc_sram_init_tab[i].access); } request_irq(RDC_SRAM_IRQn, 0, rdc_sram_IrqHandler, (void *)rdc); rdc_sram_irq_enable(rdc, RDC_SRAM_IRQ_MCU | RDC_SRAM_IRQ_OTHER, 1); } void rdc_init(void) { rdc_ddr_init(RDC_DDR); rdc_sram_init(RDC_SRAM); }