[U-Boot-Users] 834x UPM Read access RAM Array (stuck?).

I'm trying to program the UPM A on the 8347E processor. Next to having bus errors while writing from Linux (RAM words for HPI are not correct yet, but that's something I have to figure out), I'm having problems with reading the RAM words back out for testing/debugging/verification.
As the upm_config of for the 83xx processors is not yet implemented, I am using the following code as described on 10-63 to program the UPM [1]:
This is a write cycle (working):
inline void upm_write32(u32 data) { volatile immap_t *im = (immap_t *)CFG_IMMRBAR; u32 mdr; u32 mad;
/* read the current MAD */ mad = (im->lbus.mamr & MnMR_MAD_MSK);
/* set MDR */ im->lbus.mdr = data; /* Read the MDR back to ensure the data has been saved */ mdr = im->lbus.mdr;
/* dummy write */ *((u32*)im->sysconf.lblaw[1].bar) = 0xffffffff; putc('.');
while((im->lbus.mamr & MnMR_MAD_MSK) == mad){ /* dummy write */ *((u32*)im->sysconf.lblaw[1].bar) = 0xffffffff; putc('#'); } }
From all the tests I've done, the MAD is incremented what should mean that the write to the UPM RAM array was successful. Filling out the array itself is done with the following code:
void init_upma(void) { volatile immap_t *im = (immap_t *)CFG_IMMRBAR; u32 mad; u32 i;
/* 1. Set up BRn and ORn registers, done during cpu_init and * set in the platform header file. */
/* 2. Write patters into the RAM array. */ im->lbus.mamr = (MnMR_OP_WARR | MnMR_DS_CLK_4 | MnMR_GPL4_EN | MnMR_RFL_1 | MnMR_WFL_1 | MnMR_TFL_1); /* Since the result of any update to the MnMR/MDR register must * be in effect before the dummy read or write to the UPM region, * a write to MnMR/MDR should be followed immediately by a read of * MnMR/MDR */ /* Read mamr back out */ mad = (im->lbus.mamr & MnMR_MAD_MSK);
for(i=0;i<0x40;i++){ if(!(i%8))printf("\n"); printf("%#2.2x/%#2.2x ",i,hpi_write_timing[i]); upm_write32(hpi_write_timing[i]); } putc('\n');
/* 3. Program MRTPR, LURT, and MAMR[RFEN] if refresh is required. */ /* Nope */
/* verify the UPM RAM array by reading and printing the values * back out */ printf("Read UPMA Ram words back out: (start @%#8.8x)\n",mad); /* debug, read the MDR back out */ im->lbus.mamr = (MnMR_OP_RARR | MnMR_DS_CLK_4 | MnMR_GPL4_EN | MnMR_RFL_1 | MnMR_WFL_1 | MnMR_TFL_1); mad = (im->lbus.mamr & MnMR_MAD_MSK);
for(i=0;i<0x40;i++){ if(!(i%8))printf("\n"); printf("%#2.2x ",upm_read32()); } putc('\n');
/* 4. Program MnMR. */ /* normal operation */ im->lbus.mamr = ~MnMR_OP_MSK & ( MnMR_DS_CLK_4 | MnMR_GPL4_EN | MnMR_RFL_1 | MnMR_WFL_1 | MnMR_TFL_1); mad = (im->lbus.mamr & MnMR_MAD_MSK); printf("normal MAD is %#x.\n",mad); }
The read code is as follows (some code has a cnt limit due to the fact that the MAD address is never incremented as it should (10-64 LBC chapter):
inline u32 upm_read32(void) { volatile immap_t *im = (immap_t *)CFG_IMMRBAR; u32 mdr=0; u32 mad; u32 cnt = 0;
/* read the current MAD */ mad = (im->lbus.mamr & MnMR_MAD_MSK); printf("%#2.2x/",mad); /* dummy read access */ mdr = *((u32*)im->sysconf.lblaw[1].bar); putc('.');
/* limit re-read to 5 */ while(((im->lbus.mamr & MnMR_MAD_MSK) == mad) && (cnt++<5)){ mdr = *((u32*)im->sysconf.lblaw[1].bar); putc('#'); } /* read the MDR */ mdr = im->lbus.mdr;
return mdr; }
As you can see from the output (cf. infra), the MAD address does not increment as it should and the output is stuck on the last word written to the UPM (actually, for this, all words are 0xffffffff, but I've tested this and the bus address seems to get stuck to @the last written word).
U-Boot 1.1.6 (Nov 20 2006 - 11:40:51) MPC83XX
Clock configuration: Coherent System Bus: 264 MHz Core: 396 MHz Local Bus: 33 MHz CPU: MPC83xx, Rev: 1.1 at 396 MHz Board: Barco BARCO834XG1 Platform
0x00/0xffffffff .0x01/0xffffffff .0x02/0xffffffff .0x03/0xffffffff .0x04/0xffffffff . 0x08/0xffffffff .0x09/0xffffffff .0x0a/0xffffffff .0x0b/0xffffffff .0x0c/0xffffffff . 0x10/0xffffffff .0x11/0xffffffff .0x12/0xffffffff .0x13/0xffffffff .0x14/0xffffffff . 0x18/0xffffffff .0x19/0xffffffff .0x1a/0xffffffff .0x1b/0xffffffff .0x1c/0xffffffff . 0x20/0xffffffff .0x21/0xffffffff .0x22/0xffffffff .0x23/0xffffffff .0x24/0xffffffff . 0x28/0xffffffff .0x29/0xffffffff .0x2a/0xffffffff .0x2b/0xffffffff .0x2c/0xffffffff . 0x30/0xffffffff .0x31/0xffffffff .0x32/0xffffffff .0x33/0xffffffff .0x34/0xffffffff . 0x38/0xffffffff .0x39/0xffffffff .0x3a/0xffffffff .0x3b/0xffffffff .0x3c/0xffffffff . Read UPMA Ram words back out: (start @0x00000000)
0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xffffffff 0x00/.#####0xfffff normal MAD is 0x0. HPI: access enabled. BR1 0xe2401081. OR1 0xffff9006. LBLAWBAR1 0xe2400000. LBLAWAR1 0x8000000e. MAMR 0xc44440.
The board configuration is a minor modification of the MPC8349EMDS port with BCSR re-cycled to be used for HPI access with UPM A.
/* * HPI access on the local bus, 16 bit wide */ /* *** Start HPI *** */ #define CFG_HPI 0xE2400000 /* HPI Base Address */ #ifdef CFG_HPI #define CFG_BR1_PRELIM (0xE2400000 | /* HPI Base address */ \ BR_MS_UPMA | /* UPMA */ \ BR_PS_16 | /* 16 bit port size */ \ BR_V) /* valid */ #define CFG_OR1_PRELIM (0xffff8000 | /* Addres mask */ \ OR_UPM_BCTLD | /* Buffer Control disable */ \ OR_UPM_TRLX | /* Timing relaxed */ \ OR_UPM_EHTR) /* 8 idle clock cycles */ #define CFG_LBLAWBAR1_PRELIM CFG_HPI /* window base at HPI base */ #define CFG_LBLAWAR1_PRELIM 0x8000000E /* 32 kB window size */ #endif
Since I only get bus errors when writing words on the WSS offset other than _NOT_USED_ (0xFFFFFFFF), the UPM should be selected, which in turn leads me to believe that the base configuration should not be that far off.
Any pointers as to what might be wrong here?
[1] If all works as expected, I'll merge it in the upmconfig code for the 83xx processors.

Marc Leeman wrote:
I'm trying to program the UPM A on the 8347E processor. Next to having bus errors while writing from Linux (RAM words for HPI are not correct yet, but that's something I have to figure out), I'm having problems with reading the RAM words back out for testing/debugging/verification.
Looks to me like you're having an out-of-order problem.
I wrote a version of your function some time ago, and included it in the set of changes for the 83xx tree that was made available to Wolfgang a few weeks ago, but he hasn't pulled them yet. You can find those changes here:
http://opensource.freescale.com/git?p=u-boot-83xx.git;a=summary
For your convenience, here's the upmconfig() function I wrote:
void upmconfig (uint upm, uint *table, uint size) { #if defined(CONFIG_MPC834X) volatile immap_t *immap = (immap_t *) CFG_IMMR; volatile lbus83xx_t *lbus = &immap->lbus; volatile uchar *dummy = NULL; const u32 msel = (upm + 4) << BR_MSEL_SHIFT; /* What the MSEL field in BRn should be */ volatile u32 *mxmr = &lbus->mamr + upm; /* Pointer to mamr, mbmr, or mcmr */ uint i;
/* Scan all the banks to determine the base address of the device */ for (i = 0; i < 8; i++) { if ((lbus->bank[i].br & BR_MSEL) == msel) { dummy = (uchar *) (lbus->bank[i].br & BR_BA); break; } }
if (!dummy) { printf("Error: %s() could not find matching BR\n", __FUNCTION__); hang(); }
/* Set the OP field in the MxMR to "write" and the MAD field to 000000 */ *mxmr = (*mxmr & 0xCFFFFFC0) | 0x10000000;
for (i = 0; i < size; i++) { lbus->mdr = table[i]; __asm__ __volatile__ ("sync"); *dummy; /* Write the value to memory and increment MAD */ __asm__ __volatile__ ("sync"); }
/* Set the OP field in the MxMR to "normal" and the MAD field to 000000 */ *mxmr &= 0xCFFFFFC0; #else printf("Error: %s() not defined for this configuration.\n", __FUNCTION__); hang(); #endif }

I wrote a version of your function some time ago, and included it in the set of changes for the 83xx tree that was made available to Wolfgang a few weeks ago, but he hasn't pulled them yet. You can find those changes here:
Thanks,
I switched to your function (since this is the one that will be merged in u-boot anyway) and it still hangs while programming UPM A (writing) (so exactly the same behaviour as before).
When we switched to UPM B (no other change but CFG_BR1_PRELIM and the upmconfig call), we started seeing the expected signals that we programmed in our RAM for HPI.
to be continued...

Marc Leeman wrote:
I wrote a version of your function some time ago, and included it in the set of changes for the 83xx tree that was made available to Wolfgang a few weeks ago, but he hasn't pulled them yet. You can find those changes here:
Thanks,
I switched to your function (since this is the one that will be merged in u-boot anyway) and it still hangs while programming UPM A (writing) (so exactly the same behaviour as before).
When we switched to UPM B (no other change but CFG_BR1_PRELIM and the upmconfig call), we started seeing the expected signals that we programmed in our RAM for HPI.
Although my function is supposed to handle all UPMs, I've only tested it with UPM A, because that's what my 8349 ITX uses for CF programming. It's odd that UPM A doesn't work for you but UPM B does.
I don't know a whole lot about the UPM, but doesn't the board layout determine which UPM you can use? So maybe, for whatever device you're programming, you have to use UPM B?
participants (2)
-
Marc Leeman
-
Timur Tabi