Re: [U-Boot] [PATCH] ftsmc020: enhance for features and asm support.

Dear Macpaul Lin,
Please keep the mailing list on Cc: (re-added)
In message AANLkTinYJhoGrA7ZAVUQxwByrkWNqomCBFWiJG_+3+0e@mail.gmail.com you wrote:
I repeat again: I consider this manual unrolling of the nested structs a Bad Thing. You should have separate offsets for each of the nested structs.
The above code is really a rework for a nested structs. The origin code looks like, Moreover, the structure of ftsmc020 was nested like struct ftsmc020 { struct { unsigned int cr; /* 0x00, 0x08, 0x10, 0x18 */ unsigned int tpr; /* 0x04, 0x0c, 0x14, 0x1c */ } bank[4]; unsigned int pad[8]; /* 0x20 - 0x3c */ unsigned int ssr; /* 0x40 */ }
After rewrote it becomes struct ftsmc020 { unsigned int bank0_cr; unsigned int bank0_tpr; unsigned int bank1_cr; unsigned int bank1_tpr; unsigned int bank2_cr; unsigned int bank2_tpr; unsigned int bank3_cr; unsigned int bank3_tpr; unsigned int pad[8]; unsigned int ssr; }
Did I misunderstand what you exactly meant?
Yes, indeed. Unnesting means to move the inner struct declaration outside, like that:
struct ftsmc020_bank { unsigned int cr; unsigned int tpr; };
struct ftsmc020 { struct ftsmc020_bank bank[4]; unsigned int pad[8]; unsigned int ssr; };
Again: if you need larger numbers of such entries you are doing something fundamentally wrong. Reconsider your coding style. What exactly enforces you to use assembly?
This is because writing assembly code (lowlevel_init) is really a necessity for setting the timing and power outpur correctly to these registers (SMC, SDMC, PMU).
What exactly prevents you from writing the very same code in C?
It is required to give a correct setting to PMU and SMC to make the onboard DRAM works correctly before the code is loaded from ROM to DRAM and then set up stack for C environemnt.
We take care to provide global data and an initial stack very, very early in the initialization sequence. You canuse C code long before you can access the system RAM.
Hence assembly code to setting SMC and PMU in lowlevel_init is a necessity
I seriously doubt that. Just because many boards are writen that way does not mean that's how it must be done - actualy many just copied existing bad examples without thinking.
Best regards,
Wolfgang Denk

HI Wolfgang,
This is because writing assembly code (lowlevel_init) is really a necessity for setting the timing and power outpur correctly to these registers (SMC, SDMC, PMU).
What exactly prevents you from writing the very same code in C?
It is required to give a correct setting to PMU and SMC to make the onboard DRAM works correctly before the code is loaded from ROM to DRAM and then set up stack for C environemnt.
I've traced the start up code of MIPS and POWERPC architecture. They still have direct access to dram for setting up the small stack (<4KB) for C environment.
Ex. In the code in mips/start.S li t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET la sp, 0(t0)
la t9, board_init_f jr t9 nop
If you do not have direct ram access, you still need have something like internal "sram" to set up this small stack like "arch/powerpc/cpu/mpc5xx/start.S" /* Initialize some SPRs that are hard to access from C */ /*----------------------------------------------------------------------*/
lis r3, CONFIG_SYS_IMMR@h /* Pass IMMR as arg1 to C routine */ lis r2, CONFIG_SYS_INIT_SP_ADDR@h ori r1, r2, CONFIG_SYS_INIT_SP_ADDR@l /* Set up the stack in internal SRAM */ /* Note: R0 is still 0 here */ stwu r0, -4(r1) /* Clear final stack frame so that */ stwu r0, -4(r1) /* stack backtraces terminate cleanly */
However, after I have double confirmed with the hardware and architecture colleagues. We do not have both internal SRAM nor have direct access to RAM to setup this initial stack.
More then that, the initial timing and parameters setting in the SMC registers for driving the on board DRAM was not correct for store the initial stack to DRAM.
So it is necessary to set the correct timing to the registers in the SMC for even just to setup the initial stack to on board DRAM in lowlevel_init.S.
We take care to provide global data and an initial stack very, very early in the initialization sequence. You canuse C code long before you can access the system RAM.
Hence assembly code to setting SMC and PMU in lowlevel_init is a necessity
There is not only the work to set SMC in lowlevel_init is enough, correctly to set a parameters to PMU is also necessary. This is because PMU will management the PLL/DLL to generate correct timing to DRAM, AHB, and other peripheral devices. The hardware initial value of this PLL/DLL was not correct for help the DRAM access also. Even I set the correct timing to SMC (DRAM) was not enough, it is required to set PMU also. Hence we need to set the correct value for PMU in lowlevel_init.S. So there are needs for our board to write asm to set those parameters.
Hope you can understand the above explanations. If you have any questions please let me know.
participants (2)
-
Macpaul Lin
-
Wolfgang Denk