Hi, On 01-03-15 19:42, Vishnu Patekar wrote:
Allwinner A33 tablets comes with the libdram binary, fortunately I've found the libdram code at https://github.com/realthunder/a33_bootloader/tree/master/basic_loader/bsp/bsp_for_a67.
Ah, that is both good and bad...
I've integrated it with mainline u-boot, still lot to do to post it to upstream
Integrated sounds as if you've copied pieces of code from the bsp code you've found into mainline u-boot. That is a big no no (this the bad part). AFAIK the bsp code does not come with a GPL license header, and Allwinner does not want to release these bits under the GPL for whatever reasons, a lot can be said about this, but in the end currently the bsp code is not GPL licensed, so we cannot use it / copy from it. There can be no discussion on this, when you're submitting this upstream you must not have any literal copied code in the patch you're sending upstream. You can use non copyrightable information from the bsp sources like register names and the initialization algorithm (IANAL), but you must 100% write your own code! I've been working on A33 dram support too, without any source code access, instead I've been tracing what the boot0 machine code does and going from there. What I've sofar is that the code first inits the DRAM PLL / cmu dram registers, it seems that the A33 has 2 dram pll-s and that one of the dram_para fields configures which pll to use and configures some sigma-delta pattern to reduce rf interference, at least on my A33 tablet the code seems to want to pick the new / second dram pll. But I see no reason why the first one should not work, so for now if I were you I would just use the A23 dram pll / cmu setup code modified to set the one or 2 extra reset / enable bits the A33 has, but still using the old / first dram pll, we can always add support for the new one later. Then the boot0 code calculates a load of timing parameters and writes these to registers. I've already written my own C-code reproducing the init algorithm from boot0 for this (attached) this is GPL code and you should be able to use this to replace a chunk of the bsp code. Note that I found 2 code paths based on a tpr13 bit (iirc) one for autoconfig, and one for reading values from the tpr dram_para values, my code supports only autoconfig, you can add a printf to warn if manual config is requested and still keep using autoconfig. The same goes for any other code paths were there is both a manual and an auto option, look at what actual shipped tablets are using, only support that and print a warning for the other case, were possible always use autoconfig. After this boot0 does more stuff, but this is as far as I've gotten and currently I've other priorities. If I were you I would start with the existing dram_sun6i.c from upstream u-boot, as the A33 DRAM controller seems to be closest to the A31 one, then add in the dram_sun8i.c pll init code, and the timing stuff which I've already written, and then see where the initialization algorithm is different for the A33 and modify the dram_sun6i.c code to match what is needed to get the A33 going, if extra code is needed you MUST write NEW code. When you submit support for this upstream you must include a Signed-off-by, and thereby you are declaring that the code is all your own and that you've the right to submit this code under the GPL license, this means that there must be absolutely no copied code in your upstream patch submission! Also see: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches Section "11) Sign your work
Basic A33 support including dram init available in my personal repo https://github.com/vishnupatekar/u-boot-sunxi/tree/a33-dram I could able to boot u-boot over fel, and get u-boot command prompt on microSD pins which are multiplexed with UART0. The device page for A33 tablet which I've is here: http://linux-sunxi.org/Softwinner_astar-rda
Thanks for your work on this, and sorry if I sound a bit harsh above, but I really need to be strict about not allowing any non GPL code into u-boot. Regards, Hans
#include <stdio.h> #define readl(reg) 0 #define writel(val, reg) printf("writel %08x: %08x\n", reg, val) #define clrsetbits_le32(reg, clr, set) printf("clr set %08x: %08x, %08x\n", reg, clr, set) #define u32 unsigned int struct dram_para { u32 clock; u32 type; u32 zq; u32 odt_en; u32 para1; u32 para2; u32 mr0; u32 mr1; u32 mr2; u32 mr3; u32 tpr0; u32 tpr1; u32 tpr2; u32 tpr3; u32 tpr4; u32 tpr5; u32 tpr6; u32 tpr7; u32 tpr8; u32 tpr9; u32 tpr10; u32 tpr11; u32 tpr12; u32 tpr13; }; static struct dram_para dram_para = { .clock = 480, .type = 3, .zq = 123, .odt_en = 1, .para1 = 0x10f20200, .para2 = 0, .mr0 = 0x1840, .mr1 = 64, .mr2 = 8, .mr3 = 0, .tpr0 = 0x0048a192, .tpr1 = 0x01b1b18d, .tpr2 = 0x00076052, .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .tpr6 = 0, .tpr7 = 0, .tpr8 = 0, .tpr9 = 0, .tpr10 = 0, .tpr11 = 0, .tpr12 = 0xa8, .tpr13 = 0x900, }; int main(void) { u32 t4ns_min_3, t4ns_min_4, t5ns_min_4, t7_5ns_min_3, val; /* Note some values are always +1, rather then rounded up */ u32 t4ns = (dram_para.clock * 4 + 999) / 1000; u32 t5ns = (dram_para.clock * 5 + 999) / 1000; u32 t7_5ns = (dram_para.clock * 15 + 1999) / 2000; /* * Original boot0 code contains a bug here, it calculates the rounding * for 17.5ns, then adds it to the unrounded ticks needed for 19 ns. */ u32 t19ns = (dram_para.clock * 19 + 999) / 1000; u32 t25ns = (dram_para.clock * 25 + 999) / 1000; /* * Original boot0 code contains a bug here, it calculates the rounding * for 25ns, then adds it to the unrounded ticks needed for 26.5 ns. */ u32 t26_5ns = (dram_para.clock * 53 + 1999) / 2000; u32 t175ns = (dram_para.clock * 175 + 999) / 1000; u32 t360ns = dram_para.clock * 360 / 1000 + 1; u32 t3900ns = (dram_para.clock * 3900 + 999) / 1000; u32 t1us = dram_para.clock + 1; u32 t200us = dram_para.clock * 200 + 1; u32 t500us = dram_para.clock * 500 + 1; t4ns_min_3 = t4ns; if (t4ns_min_3 < 3) t4ns_min_3 = 3; t4ns_min_4 = t4ns; if (t4ns_min_4 < 4) t4ns_min_4 = 4; t5ns_min_4 = t5ns; if (t5ns_min_4 < 4) t5ns_min_4 = 4; t7_5ns_min_3 = t7_5ns; if (t7_5ns_min_3 < 3) t7_5ns_min_3 = 3; dram_para.tpr0 = (1 << 22) | (t25ns << 15) | (t5ns_min_4 << 11) | (t7_5ns << 6) | t26_5ns; dram_para.tpr1 = (t4ns_min_3 << 23) | (t4ns_min_4 << 20) | (t4ns_min_4 << 15) | (t7_5ns_min_3 << 11) | (t7_5ns << 6) | t19ns; dram_para.tpr2 = (t175ns << 12) | (t3900ns / 32); dram_para.mr0 = 0x1c70; dram_para.mr2 = 0x18; val = readl(0x01c62000); val &= 0xff000ff0; val |= ((dram_para.para2 >> 4) & 0x01) << 24; val |= 1 << 22; val |= ((dram_para.tpr13 >> 5) & 0x01) << 19; val |= dram_para.type << 16; val |= (~dram_para.para2 & 1) << 12; val |= ((dram_para.para1 >> 28) & 0x01) << 2; val |= ((dram_para.para2 >> 12) & 0x03) << 0; writel(val, 0x01c62000); writel(dram_para.mr0, 0x1c63030); writel(dram_para.mr1, 0x1c63034); writel(dram_para.mr2, 0x1c63038); writel(dram_para.mr3, 0x1c6303c); writel(((t7_5ns_min_3 + 6) << 24) | (t25ns << 16) | (24 << 8) | t19ns, 0x1c63058); writel((t4ns_min_3 << 16) | (t4ns_min_4 << 8) | t26_5ns, 0x1c6305c); writel((4 << 24) | (6 << 16) | (5 << 8) | (t4ns_min_4 + 6), 0x1c63060); writel((4 << 12) | 12, 0x1c63064); writel((t7_5ns << 24) | (2 << 16) | (t5ns_min_4 << 8) | t7_5ns, 0x1c63068); writel((5 << 24) | (5 << 16) | (4 << 8) | 3, 0x1c6306c); clrsetbits_le32(0x1c63078, 0xffff, 0x3308); writel((2 << 24) | (4 << 16) | (1 << 8) | 2, 0x1c63080); writel((t360ns << 20) | t500us, 0x1c63050); writel((t1us << 20) | t200us, 0x1c63054); writel(((t3900ns / 32) << 16) | t175ns, 0x1c63090); return 0; }
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot