Hi,everyone

I am writing a linux driver for omap3530 gpmc to communicate with a FPGA.

I configure the GPMC to Synchronous,Data/Address non-multiplexed,16bit Mode.

At first I write a simple code to check the read and write functions.

Here is what I did:

#define MY_CS 4
#define SLV_NUM 1

static void __iomem *gpmc_base;
static void __iomem *gpmc_cs4_base=0;
unsigned long cs4_mem_base;

static u32 gpmc_read_reg(int idx)
{
    return __raw_readl(gpmc_base + idx);
}
static void gpmc_write_reg(int idx, u32 val)
{
    __raw_writel(val, gpmc_base + idx);
}
u32 read_from_mcb(int idx)
{
    return __raw_readl(gpmc_cs4_base+idx*4);
}
void write_to_mcb(int idx, u32 val)
{
    __raw_writel(val, gpmc_cs4_base+ idx*4);
}

int my_gpmc_init()
{
    gpmc_write_reg(GPMC_SYSCONFIG, 0x18);
    gpmc_write_reg(GPMC_CONFIG, 0x12);

    //sychronous,16bit,NOR,no multiplexed,GPMC_CLK==GPMC_FCLK
    gpmc_cs_write_reg(MY_CS, GPMC_CS_CONFIG1,0x28001000);

    if (gpmc_cs_request(MY_CS, SZ_16M, &cs4_mem_base) < 0) 
    {
        printk("<1>Failed to request GPMC mem for cs4\n");
        return -1;
    }
    printk("<1>cs4_mem_base:%x\n",cs4_mem_base);
    gpmc_cs4_base=ioremap(cs4_mem_base,SZ_16M);
    return 0; 
}

void mcb_init(void)
{
    u32 i;
    int offset=0;
 
    //off mcb 
    write_to_mcb(1, 0);

    //mcb configure
    write_to_mcb(0, 1);//comm.m_s = 1;
    write_to_mcb(3, SLV_NUM);//comm.slv_num = 1;
    write_to_mcb(4, 5);//comm.t_cyclic = 5; //500us

    for(i = 0; i < SLV_NUM; i++)
   {
            offset = 112 + i*50;
            write_to_mcb(offset, (i+3)<<8);//addr.addr_s = (i+3)<<8;
            write_to_mcb(offset+1, DA_M1);//addr.addr_m = DA_M1; 
   }

    //on mcb 
    write_to_mcb(1, 1);

    printk("<1>read back checking......\n");
    
printk("<1>on:%lu(1)\nm_s:%lu(1)\nslv_num:%lu(1)\nt_cyclic:%lu(5)\n",read_from_mcb(1),read_from_mcb(0),read_from_mcb(3),read_from_mcb(4));
 }

int init_module(void)
{
    int ret;
    u32 l;
    unsigned long rate;
      
    l = OMAP34XX_GPMC_BASE;
    gpmc_base = ioremap(l, SZ_4K);

    my_gpmc_init();
    if(gpmc_cs4_base!=0)
    {
        printk("<1>gpmc_cs4_base:%x",gpmc_cs4_base);
        mcb_init();
    }
    return 1;
}

void cleanup_module(void)
{
      printk("<1>cleanup module ......\n");
}

As you see,in function mcb_init(void),I write data to the FPGA and read them 
back for checking.

The expected results should be "1,1,1,5" but they turn out to be all zero!

Have I done anything wrong?

I use "gpmc_cs_request(MY_CS, SZ_16M, &cs4_mem_base) "to get the phsical 
address of FPGA,

then ioremap it by using "gpmc_cs4_base=ioremap(cs4_mem_base,SZ_16M)".As told 
by TI employee

ioremap is not necessary. 
http://e2e.ti.com/support/dsp/omap_applications_processors/f/447/t/62630.aspx

But when I directly use "cs4_mem_base" as base address,I got the segmentation 
fault!

By the way,gpmc synchronous mode is only for devices with limited 2K memory 
range.

then how to use gpmc_cs_request() correctly?

Is there anyone can help?

thanks very much!
11-06-16 

--------------------------------------------------------------------------------
Levin





_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to