Hi all, the DDR clock of i.mx6 is 528MHz on boot time, but I want to change it to lower(may be 400MHz).
I read the Datasheet and found the below introduction:
"
18.2.1.5.3 PLL clock change
If software wants to change pll clock output of a specific pll, or if software wants to stop
a specific pll, then software needs first to move all the clocks generated from this pll to
another pll which is not changed.
This should be done via the glitch less mux's for the clocks which cant be stopped (core
and bus clocks). Procedure of PLL clock change is described in anatop module spec.
"
But I can't found the "anatop module spec".
By the way, in i.mx5,the clock is configure int the file of "lowlevel_init.S" by the macro of "init_clock" & "setup_pll pll, freq",
But in i.mx6,the macro of "setup_pll pll, freq" is empty and "PLL1, PLL2, and PLL3 are configured by ROM", so I have no idea of how to change DDR clock of i.mx6.
If anyone can help me please?
Hi,
I am trying to calibrate imx6ul processor which is having MT41J128M16 DDR3 SDRAM, I would like to calibrate the DDR below 396MHZ. I have updated the calibration sheet with 300MHZ and tried to calibrate.
Calibration was successful but device still runs in 396 MHZ. Will imx6ul work below 396MHZ DDR clock frequency?
I have updated all the Write leveling, DQS Gating, Read and write calibration register values in my .cfg file, device got booted successfully but it still runs in 396MHZ frequency.
Could you please let me know where else I have update to make the device runs in 297MHZ clock frequency.
I have attached my calibration sheet and DDR calibration log here.
Kindly provide your inputs on the same. Please do let me know if I am missing out on anything
Thanks,
Sheik Ajith
Not to go off-topic, but on another board my company made (based on a Samsung chipset) there was an issue with DDR initialization. Simply put, when writing values to the DDR, we weren't able to read the same values. Due to limited documentation, the team fixed that issue with 'trial-and-error'. Basically testing out different combinations for the DDR settings until they found something that worked; obviously it took them a long time to fix things.
I'm worried about facing the same problem with an upcoming iMX6 dual core board we are designing. From what I've understood with this discussion, the DDR gets initialized in the boot ROM and neither uboot nor linux touch that initialization afterwards. Is this correct? The reference board we have is the iMX6 sabresd (quad core). From the schematics, I understand that its databus is 64bits with 1GB worth of DDR3. Our target board is designed with a databus of 32-bits of 1GB DDR3, using chipsets from a different manufacturer.
Is the DCD table as defined in the uboot source file "board/freescale/mx6q_sabresd/flash_header.S" my only point for DDR configuration? (I'm using the uboot obtained from git://git.freescale.com/imx/uboot-imx.git as suggested by the 'Android_User_Guide.pdf' document) Or am I missing something obvious?
Hi Abraham,
I have the same understanding as you, the DDR is initialize in the first couple of call to the CPU before U-Boot is copied into RAM. After that nobody touch it... You will probably have to adjust the DDR configuration file depending on your memory chipset. The DDR configuration file (board/freescale/mx6q_sabresd/flash_header.S or board\freescale\imx\ddr\mx6q_4x_mt41j128.cfg) depend on which version of u-boot you are using. The latest u-boot version use the .cfg file.
Let me know if you have more quesitons, I will try my best to help you.
Regards
Patrice
Thanks for your reply Patrice.
Its good to know that I'm not the only developer who came to the conclusion that the DDR cannot be configured AFTER uboot starts. But that puzzles me too. The iMX6 reference manual has a chapter called "Multi Mode DDR Controller" (chapter 44) which speaks of configuring the MMDC with information like DDR type ... etc. If, as a developer I can't access (or do anything meaningful) with the registers it mentions, why bother with having such a chapter at all?
Off to decypher the DCD table,
Abraham V.
Hi,
There was some code to modify the DDR clock and do the calibration ( see attached files). It worked in baremetal and I was trying to integrate inside u-boot... For now, I didn't find the correct place to put it inside u-boot. I have to find the place where I can implement this logic before we the jump into RAM.
Any ideas for the correct place?
Thanks
Pat
Hi, all
If I remembered right, we didn't support changing DDR clk in runtime under uboot. Which means if you want a dedicated DDR freq, you need to change the DCD table as you mentioned upper, which is in charge of DDR controller's initialization. Different DDR freq may need different DDR script(DCD setting) to make it work stably.
Hi, Yongcai,
I also hadDDR clk issue that reducing 528MHZ to 400MHZ caused u-boot halted. therefore I still use 528MHZ. Also I am trying to figure out how to reduce 1 Gigabyte DDR3 RAM to 512Mega Bytes (half of 1 Gigabyte) in mx6 sabresd code of '/u-boot- fslc/v2016.07+gitAUTOINC+e6b42411ab-r0 ' and hardware design. Please see my 'Question X'.
The original reference design of i.MX6 had a total of 1 Gigabyte DDR3 RAM. The implementation was using four Micron MT41K128M16 parts. Each part is a 256 Mega Bytes ( 256 M * 4 = 1Gbytes).
Question 1: Is there any hardware change for reducing 1 Gigabyte DDR3 RAM to 512MegaByte?
My hardware design follows the original reference design for 1 Gigabyte DDR3 RAM, but there are only two MT41K128M16 parts soldered on a board. That means that there are only 512 Mega bytes (256M * 2 = 512 M) physical ram parts.
To extend RAM size, there should be hardware changes. But in my case, I am trying to reduce RAM. Therefore, 1 Gigabyte RAM hardware should accommodate 512Mbyte RAM without any modification. Correct?
Question 2: Let's assume that there is no change in hardware which is same to 1Gbyte RAM original reference design, what should be changed in u-boot software?
Here are what MDCTL and MDMISC are shown in "MX6DL_SabreSD_DDR3_register_programming_aid_v2.1.xlsx "
Reg name Reg address Reg value
MDCTL 0x021B0000 0x831A0000
MDMISC 0x021B0018 0x00001740
Here is what MDCTL and MDMISC are shown in
"/home/sw/fsl-community-bsp/build/tmp/work/imx6dlsabresd-poky-linux-gnueabi/u-boot- fslc/v2016.07+gitAUTOINC+e6b42411ab-r0/git/board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg".
DATA 4 0x021b0000 0x831A0000
DATA 4 0x021b0018 0x00081740 (Question 3, why this value is not 0x00001740? )
Here is what MDCTL and MDMISC are shown in
"/home/sw/fsl-community-bsp/build/tmp/work/imx6dlsabresd-poky-linux-gnueabi/u-boot-fslc/v2016.07+gitAUTOINC+e6b42411ab-r0/git/board/freescale/mx6sabresd/mx6sabresd.cfg".
DATA 4 0x021b0000 0x831A0000
DATA 4 0x021b0018 0x00001740
Here is how 1 Gbytes Ram has been calculated in
"/home/sw/fsl-community-bsp/build/tmp/work/imx6dlsabresd-poky-linux-gnueabi/u-boot-fslc/v2016.07+gitAUTOINC+e6b42411ab-r0/git/arch/arm/imx-common/cpu.c"
---------------------------code in cpu.c ---------------------------------------------------------
#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
#if defined(CONFIG_MX53)
#define MEMCTL_BASE ESDCTL_BASE_ADDR
#else
#define MEMCTL_BASE MMDC_P0_BASE_ADDR /* Question 4: MMDC_P0_BASE_ADDR must be 0x021b0000, correct? */
#endif
static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9}; /*Question 5: how do I know these values are correct? */
static const unsigned char bank_lookup[] = {3, 2}; /*Question 6: how are these values associated with ram bank? */
/* these MMDC registers are common to the IMX53 and IMX6 */
struct esd_mmdc_regs {
uint32_t ctl;
uint32_t pdc;
uint32_t otc;
uint32_t cfg0;
uint32_t cfg1;
uint32_t cfg2;
uint32_t misc;
};
#define ESD_MMDC_CTL_GET_ROW(mdctl) ((ctl >> 24) & 7)
#define ESD_MMDC_CTL_GET_COLUMN(mdctl) ((ctl >> 20) & 7)
#define ESD_MMDC_CTL_GET_WIDTH(mdctl) ((ctl >> 16) & 3)
#define ESD_MMDC_CTL_GET_CS1(mdctl) ((ctl >> 30) & 1)
#define ESD_MMDC_MISC_GET_BANK(mdmisc) ((misc >> 5) & 1) /* Question 7: it seems that MDMISC register needs a new value to reduce Ram from 1 Gbytes to 512 bytes. What is the exact value ? For 1Gytes value, it is 0x00001740 */
/*
* imx_ddr_size - return size in bytes of DRAM according MMDC config
* The MMDC MDCTL register holds the number of bits for row, col, and data
* width and the MMDC MDMISC register holds the number of banks. Combine
* all these bits to determine the meme size the MMDC has been configured for
*/
unsigned imx_ddr_size(void)
{
struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE;
unsigned ctl = readl(&mem->ctl);
unsigned misc = readl(&mem->misc);
int bits = 11 + 0 + 0 + 1; /* row + col + bank + width */ /* Question 8: where do 11, 0, 0, 1 values come ? */
bits += ESD_MMDC_CTL_GET_ROW(ctl);
bits += col_lookup[ESD_MMDC_CTL_GET_COLUMN(ctl)];
bits += bank_lookup[ESD_MMDC_MISC_GET_BANK(misc)];
bits += ESD_MMDC_CTL_GET_WIDTH(ctl);
bits += ESD_MMDC_CTL_GET_CS1(ctl);
/* The MX6 can do only 3840 MiB of DRAM */
if (bits == 32)
return 0xf0000000;
return 1 << bits;
}
#endif
-----------------------end of code in cpu.c -----------------------------------------------------
Thanks.
Ok thanks for info! I will stop trying to change it in runtime under u-boot... Do you already have a working script for 500Mhz or 400Mhz so I can based myself on it?
Best regards
Pat
Hi, Pat
Sorry, I don't have a 500M script, I only have a flash_header when I was trying 400M on iMX6Q sabresd board, this is a debug version, the script is not the latest one, you can try it to see whether it works on your board first, and you should contact the DDR owner to get the latest script for 400M.
/* Init the DDR according the init script */
ldr r0, =CCM_BASE_ADDR
/* select 400MHz for pre_periph_clk_sel */
ldr r1, =0x00060324
str r1, [r0,#0x18]
/* 64-bit DDR3 */
/* IOMUX setting */
ldr r0, =IOMUXC_BASE_ADDR
mov r1, #0x30
str r1, [r0,#0x5a8]
str r1, [r0,#0x5b0]
str r1, [r0,#0x524]
str r1, [r0,#0x51c]
str r1, [r0,#0x518]
str r1, [r0,#0x50c]
str r1, [r0,#0x5b8]
str r1, [r0,#0x5c0]
ldr r1, =0x00020030
str r1, [r0,#0x5ac]
str r1, [r0,#0x5b4]
str r1, [r0,#0x528]
str r1, [r0,#0x520]
str r1, [r0,#0x514]
str r1, [r0,#0x510]
str r1, [r0,#0x5bc]
str r1, [r0,#0x5c4]
str r1, [r0,#0x56c]
str r1, [r0,#0x578]
str r1, [r0,#0x588]
str r1, [r0,#0x594]
str r1, [r0,#0x57c]
ldr r1, =0x00003000
str r1, [r0,#0x590]
str r1, [r0,#0x598]
mov r1, #0x00
str r1, [r0,#0x58c]
ldr r1, =0x00003030
str r1, [r0,#0x59c]
str r1, [r0,#0x5a0]
ldr r1, =0x00000030
str r1, [r0,#0x784]
str r1, [r0,#0x788]
str r1, [r0,#0x794]
str r1, [r0,#0x79c]
str r1, [r0,#0x7a0]
str r1, [r0,#0x7a4]
str r1, [r0,#0x7a8]
str r1, [r0,#0x748]
str r1, [r0,#0x74c]
mov r1, #0x00020000
str r1, [r0,#0x750]
mov r1, #0x00000000
str r1, [r0,#0x758]
mov r1, #0x00020000
str r1, [r0,#0x774]
mov r1, #0x30
str r1, [r0,#0x78c]
mov r1, #0x000c0000
str r1, [r0,#0x798]
/* Initialize 2GB DDR3 - Micron MT41J128M */
ldr r0, =MMDC_P0_BASE_ADDR
ldr r2, =MMDC_P1_BASE_ADDR
ldr r1, =0x02020207
str r1, [r0,#0x83c]
ldr r1, =0x02020201
str r1, [r0,#0x840]
ldr r1, =0x02020207
str r1, [r2,#0x83c]
ldr r1, =0x02150203
str r1, [r2,#0x840]
ldr r1, =0x3E35353B
str r1, [r0,#0x848]
ldr r1, =0x3A393541
str r1, [r2,#0x848]
ldr r1, =0x41424744
str r1, [r0,#0x850]
ldr r1, =0x4937483B
str r1, [r2,#0x850]
ldr r1, =0x33333333
str r1, [r0,#0x81c]
str r1, [r0,#0x820]
str r1, [r0,#0x824]
str r1, [r0,#0x828]
str r1, [r2,#0x81c]
str r1, [r2,#0x820]
str r1, [r2,#0x824]
str r1, [r2,#0x828]
ldr r1, =0x00081740
str r1, [r0,#0x18]
ldr r1, =0x00008000
str r1, [r0,#0x1c]
ldr r1, =0x555b99a4
str r1, [r0,#0x0c]
ldr r1, =0xfe730e64
str r1, [r0,#0x10]
ldr r1, =0x01ff00db
str r1, [r0,#0x14]
ldr r1, =0x000026d2
str r1, [r0,#0x2c]
ldr r1, =0x005b0e21
str r1, [r0,#0x30]
ldr r1, =0x1b334000
str r1, [r0,#0x08]
ldr r1, =0x0003002d
str r1, [r0,#0x04]
ldr r1, =0x00000027
str r1, [r0,#0x40]
ldr r1, =0xc31a0000
str r1, [r0,#0x00]
ldr r1, =0x00000800
str r1, [r0,#0x8b8]
ldr r1, =0x04088032
str r1, [r0,#0x1c]
ldr r1, =0x0408803a
str r1, [r0,#0x1c]
ldr r1, =0x00008033
str r1, [r0,#0x1c]
ldr r1, =0x0000803b
str r1, [r0,#0x1c]
ldr r1, =0x00428031
str r1, [r0,#0x1c]
ldr r1, =0x00428039
str r1, [r0,#0x1c]
ldr r1, =0x09308030
str r1, [r0,#0x1c]
ldr r1, =0x09308038
str r1, [r0,#0x1c]
ldr r1, =0x04008040
str r1, [r0,#0x1c]
ldr r1, =0x04008048
str r1, [r0,#0x1c]
ldr r1, =0xa5380003
str r1, [r0,#0x800]
ldr r1, =0x00005800
str r1, [r0,#0x20]
ldr r1, =0x00022221
str r1, [r0,#0x818]
ldr r1, =0x00022221
str r1, [r2,#0x818]
ldr r1, =0x00000000
str r1, [r0,#0x1c]
Hello, Huang
I tried your script on i.MX6QSabreSd board,the u-boot can't start up.
I used the DCD tables(in flash_header.S) and I set values for registers according to your script.
Is there anything else that I need to do?
Thank you!
ZongbiaoLiao
Hi,
we also have a custom board based on mx6sabrelite and we need to reduce the DDR speed to 500Mhz instead of the 528Mhz as the final solution. Maybe for now the 400Mhz should be enough, but I cannot get it to work with the indication found in this post. I was hoping someone could give me some pointers....
I am using the latest u-boot release 2013.04 and it seems that the DDR initialisation structure changed a little bit. It seems there is no more flash_header.S and the way the DCD structure is declared as changed...
I modify the following line in board\freescale\imx\ddr\mx6q_4x_mt41j128.cfg, but for now the boot hang...
DATA 4 0x020e0774 0x00020000
DATA 4 0x020e078c 0x00000030
DATA 4 0x020e0798 0x000C0000
/*************MY ADDITION**************
DATA 4 0x020C4018 0x00060324
/********************************************
DATA 4 0x021b081c 0x33333333
DATA 4 0x021b0820 0x33333333
DATA 4 0x021b0824 0x33333333
Any ideas will be welcome
best regards
Patrice
Hi,
Remove the comments and put it in the starting of DCD configuration. This worked for me.
Hi Patrice,
i am working on a similar issue but on a sabre SD board. Have you tried the u-boot command clk? just stop the booting process on U-boot and type clk ddr 400. This is not a permanent change but at least in the testing phase it can help.
Leo
Hi,
which u-boot are you using? In my version this command doesn't exist... I am trying to do the integration of it from the source code I found here:
u-boot-gazelle/common/cmd_clk.c at master · bandwidthcrunch/u-boot-gazelle · GitHub
Thanks
Pat
BTW, this code should be done before DDR init, normally it should be in flash_header.S, if you use DCD mode, then you should add these config into DCD items.
Hi Yongcai,
Thanks so much for pointing me to the DCD table feature. But I add the CCM config into DCD items between IOMUXC items and MMDC items like below:
"
MXC_DCD_ITEM(37, IOMUXC_BASE_ADDR + 0x758, 0x00000000)
MXC_DCD_ITEM(38, IOMUXC_BASE_ADDR + 0x774, 0x00020000)
MXC_DCD_ITEM(39, IOMUXC_BASE_ADDR + 0x78c, 0x00000030)
MXC_DCD_ITEM(40, IOMUXC_BASE_ADDR + 0x798, 0x000C0000)
MXC_DCD_ITEM(41, CCM_BASE_ADDR + 0x18, 0x00060324) //add here
MXC_DCD_ITEM(42, MMDC_P0_BASE_ADDR + 0x81c, 0x33333333)
MXC_DCD_ITEM(43, MMDC_P0_BASE_ADDR + 0x820, 0x33333333)
MXC_DCD_ITEM(44, MMDC_P0_BASE_ADDR + 0x824, 0x33333333)
MXC_DCD_ITEM(45, MMDC_P0_BASE_ADDR + 0x828, 0x33333333)
"
and the MfgTool load u-boot fail and info "Reason is unknown,failed to run comman".
Hi, Tony
If you add one item to DCD table, some parameters need to be changed, please search the below two lines code, the DCD length must be changed, such as below, if there is 59 items, then Len = 59*8+4+4=0x1E0, so there is E001 in the dcd_hdr, and same as write_dcd_cmd, it is DC01. You can try it.
66 dcd_hdr: .word 0x40E001D2 /* Tag=0xD2, Len=59*8 + 4 + 4, Ver=0x40 */
67 write_dcd_cmd: .word 0x04DC01CC /* Tag=0xCC, Len=59*8 + 4, Param=0x04 */
Hi, Tony
See below code for reference, it makes the DDR's clock root from 396M PFD. if you want to make DDR running at 400M, you need to switch periph_clk to 400M, which is MMDC clock's parent, and periph_clk is from pre_periph_clk, so you need to switch it from 528M PLL2 to 396M PFD. Normally, 528M DDR script should work for 400M, but if you find it can NOT work, then maybe DDR script need improvement. BTW, you can set CCM_CCOSR to output mmdc_axi_ch0's clock root to CLKO pin, then you can monitor whether it is the frequency you need.
/* Init the DDR according the init script */
ldr r0, =CCM_BASE_ADDR
/* select 400MHz for pre_periph_clk_sel */
ldr r1, =0x00060324
str r1, [r0,#0x18]