I'm using EIM to connect with ADV212(HW jpeg 2000 encoder)
but, EIM write speed is too slow..
below attach file("EIM_WRITE_CS_WAVEFORM.png") is EIM's chip select waveform
I think first CS enable to second CS enable period is too large(long time)
I don't know why?
Anyone know this situation?
*Test code(infinite write loop)
#define PIXEL 0x0
adv_reg = ioremap(0x8000000,(0x8000000-4));// 128MB area
pixel_addr = adv_reg+(PIXEL*0x00400000/2);
while(1)
{
*pixel_addr = 0xAA;
}
*EIM setting values
static void setup_weimcs(void)
{
unsigned int reg;
void __iomem *nor_reg = MX6_IO_ADDRESS(WEIM_BASE_ADDR); //0x021B_8000
void __iomem *ccm_reg = MX6_IO_ADDRESS(CCM_BASE_ADDR);
/*CCM_BASE_ADDR + CLKCTL_CCGR6*/
reg = readl(ccm_reg + 0x80);
reg |= 0x00000C00;
writel(reg, ccm_reg + 0x80);
__raw_writel(0x00000020, nor_reg + 0x090);
__raw_writel(0x000109B9, nor_reg + 0x000);
__raw_writel(0x00001000, nor_reg + 0x004);
__raw_writel(0x08001100, nor_reg + 0x008);//read timing
__raw_writel(0x00000000, nor_reg + 0x00C);
__raw_writel(0x02000240, nor_reg + 0x010);//write timing
}
Hello,Shin,
Please notice here :
while(1)
{
*pixel_addr = 0xAA;
}
I think issue should be generated here. It maybe take up all times of CPU. and cpu has no time to handle other tasks.
can you help me? I do not know why the EIM do not wor on my board.Pin by the oscilloscope, no change. I config and write EIM like the following:
1.config MUX and PAD
static iomux_v3_cfg_t mx6q_sabresd_pads[] = {
.
.
.
/* eim */
MX6Q_PAD_EIM_OE__WEIM_WEIM_OE,
MX6Q_PAD_EIM_RW__WEIM_WEIM_RW,
MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT,
MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA,
MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK,
MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0,
/* 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,
/* Address Bus */
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,
};
2.set EIM register
static void mx6q_setup_eim_cs(void)
{
void __iomem *ram_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);
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");
writel(0x403304b1, ram_reg);
writel(0x0, ram_reg + 0x4);
writel(0x0f010000, ram_reg + 0x8);
writel(0x00000008, ram_reg + 0xc);
writel(0x0f040040, ram_reg + 0x10);
writel(0x00000000, ram_reg + 0x14);
writel(0x00000000, ram_reg + 0x90);
}
3.iomap(addr:0x08000000, size:0x02000000)
weim->base = devm_ioremap(&pdev->dev, res->start ,len);
if (weim->base == NULL) {
dev_err(&pdev->dev, "Failed to ioremap flash region\n");
ret = -EIO;
goto weim_err;
}
4.read and write EIM
long EIM_ioctl(struct file* pFile, unsigned int cmd, unsigned long data)
{
int val = 0;
struct eimNode* node = (struct eimNode*)data;
int *addr = 0;
if(weim == 0)
return FAIL;
switch(cmd)
{
case EIM_READ:
val = __raw_readl(weim->base + node->offset);
node->data = val;
break;
case EIM_WIRTE:
__raw_writel(node->data, weim->base + node->offset);
break;
default:
break;
}
return SUCCESS;
}
blow code is test code to test EIM write
while(1)
{
*pixel_addr = 0xAA;
}
pixel_addr pointer is address space of EIM, so continuing write to EIM without any other processing.