Problem reading and programming memory location...
Anatolij Gustschin
agust at denx.de
Sun Nov 17 01:29:33 EST 2013
Hi Lorenzo,
see my comments below.
On Fri, 15 Nov 2013 17:27:30 +0100
neorf3k <neorf3k at gmail.com> wrote:
> Hello again, I’ve tried this code, but we are not able to
> change cs4 reg value… what could be?
>
> —
>
> #define MALab_DEVICE_NAME "MALab"
> #define MPC5xxx_MM_CS4_START (MBAR_BASE + 0x0024)
> #define MPC5xxx_MM_CS4_STOP (MBAR_BASE + 0x0028)
> #define MPC5xxx_MM_IPBI (MBAR_BASE + 0x0054)
>
> #define MALab_MM_START 0x10020000U
> #define MALab_MM_END 0x10020FFFU
Please change MALab_MM_END to 0x10030000U.
> #define MALab_MM_SIZE 0x00001000U
>
> int init_module(void) { ...
> u16 cs4_start_value;
> u16 cs4_stop_value;
> u32 cs4_enable_value;
>
> u8 rvoice_ioaddr_value;
>
>
> // reserve a page of memory for our hardware /proc/iomem
> if ( check_region(MALab_MM_START,MALab_MM_SIZE) ) {
> printk (KERN_ALERT "LED init_module: memory already in use\n");
> return -EBUSY;
> }
>
>
> request_mem_region(MALab_MM_START,MALab_MM_SIZE,MALab_DEVICE_NAME);
>
>
> void __iomem *cs0_reg = ioremap ((volatile unsigned long)(MBAR_BASE + 0x0300), 4);
> void __iomem *cs3_reg = ioremap ((volatile unsigned long)(MBAR_BASE + 0x030C), 4);
>
> void __iomem *ipbi_cr = ioremap ((volatile unsigned long)(MPC5xxx_MM_IPBI), 4);
> void __iomem *cs4_start = ioremap ((volatile unsigned long)(MPC5xxx_MM_CS4_START + 2), 2);
> void __iomem *cs4_stop = ioremap ((volatile unsigned long)(MPC5xxx_MM_CS4_STOP + 2), 2);
>
> void __iomem *cs4_enable = ioremap ((volatile unsigned long)(MBAR_BASE + 0x0310), 4);
> void __iomem *cs_ctrl_reg = ioremap ((volatile unsigned long)(MBAR_BASE + 0x0318), 4);
this might work, but this is not how ioremap() supposed to be used.
The mapping is done in 4k-page granularity, so it would be better
to just map the internal register range my one ioremap() call, i.e.
reg_base = ioremap(MBAR_BASE, 0x400);
and then to calculate the register offsets, i.e.
cs0_reg = reg_base + 0x0300;
cs0_reg = reg_base + 0x030C;
...
ipbi_cr = reg_base + 0x0054;
cs4_start = reg_base + 0x0026;
cs4_stop = reg_base + 0x002a;
...
For FPGA mapping you need a separate ioremap() call of course.
> void __iomem *rvoice_ioaddr = ioremap ((volatile unsigned long)(MALab_MM_START), MALab_MM_SIZE);
>
> //disable CSO
>
> out_be32(cs0_reg, 0x0004ed00);
>
>
> //disable CS3
>
> out_be32(cs3_reg, 0x0002cf00);
>
> // enable LocalBus chip select CS4
> out_be32(ipbi_cr, 0x00290001);
The comment and the code doesn't match here, the code disables
CS4 to configure the its range, so the comment is confusing.
> cs4_start_value=in_be16(cs4_start);
> cs4_start_value=MALab_MM_START >>16;
> out_be16(cs4_start, cs4_start_value);
> cs4_stop_value=in_be16(cs4_stop);
> cs4_stop_value=MALab_MM_END >>16;
> out_be16(cs4_stop, cs4_stop_value);
Here is the problem. The _minimal_ chip select range _must_
be 64 KiB, otherwise the register access can't work. Your
current chip select 4 range is less then 1 KiB:
0x10020FFF - 0x10020000 = 0xFFF
Since you right-shift the start and stop values by 16,
the chip select start and stop registers are both 0x1002.
The resulting chip select address range is 0. Therefore
please set MALab_MM_END value to 0x10030000.
Thanks,
Anatolij
More information about the Linuxppc-dev
mailing list