Lines Matching +full:tcke +full:- +full:min +full:- +full:tck

1 // SPDX-License-Identifier: GPL-2.0+
5 * (C) Copyright 2007-2015
10 * Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
26 * Allwinner as part of the open-source bootloader release (refer to
27 * https://github.com/allwinner-zh/bootloader.git) and augments the upstream
36 * Note that the Zynq-documentation provides a very close match for the DDR
42 * (i.e. the rules for MEMC_FREQ_RATIO=2 from the Zynq-documentation apply).
48 * 1) Only DDR3 support is implemented, as our test platform (the A80-Q7
50 * 2) Only 2T-mode has been implemented and tested.
62 * The driver should be driven from a device-tree based configuration that
64 * frequency and speed-bin information)---the data structures used in the
68 * To enable a device-tree based configuration of the sun9i platform, we
70 * into SRAM A1 (40KB) and next into SRAM A2 (160KB)---which would be the
71 * stage to initialise the platform via the device-tree---before having
72 * the full U-Boot run from DDR.
79 * sub-ns timings, such as 7.5ns without losing precision or resorting to
104 /* Timing information for each speed-bin */
110 * JEDEC Standard No. 79-3F
141 /* self-refresh timings */
148 /* power-down timings */
151 struct dram_sun9i_timing tCKE; member
154 u32 tWLMRD; /* min, in nCK */
155 /* u32 tWLDQSEN; min, in nCK */
189 writel(SCHED_CONFIG, &mctl_ctl->sched); in mctl_ctl_sched_init()
190 writel(PERFHPR0_CONFIG, &mctl_ctl->perfhpr0); in mctl_ctl_sched_init()
191 writel(PERFHPR1_CONFIG, &mctl_ctl->perfhpr1); in mctl_ctl_sched_init()
192 writel(PERFLPR0_CONFIG, &mctl_ctl->perflpr0); in mctl_ctl_sched_init()
193 writel(PERFLPR1_CONFIG, &mctl_ctl->perflpr1); in mctl_ctl_sched_init()
194 writel(PERFWR0_CONFIG, &mctl_ctl->perfwr0); in mctl_ctl_sched_init()
195 writel(PERFWR1_CONFIG, &mctl_ctl->perfwr1); in mctl_ctl_sched_init()
213 if ((para->dram_clk <= 400)|((para->dram_tpr8 & 0x1)==0)) { in mctl_sys_init()
216 ccm_setup_pll6_ddr_clk((1000000 * (para->dram_clk) * 2), 0); in mctl_sys_init()
219 ccm_setup_pll6_ddr_clk((1000000 * (para->dram_clk) / 2), 1); in mctl_sys_init()
222 if (para->dram_tpr13 & (0xf<<18)) { in mctl_sys_init()
234 if(para->dram_tpr13 & (0x1<<18)) in mctl_sys_init()
240 else if(para->dram_tpr13 & (0x1<<19)) in mctl_sys_init()
246 else if(para->dram_tpr13 & (0x1<<20)) in mctl_sys_init()
252 else if(para->dram_tpr13 & (0x1<<21)) in mctl_sys_init()
273 clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL); in mctl_sys_init()
275 clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL); in mctl_sys_init()
280 setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MCTL); in mctl_sys_init()
282 setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MCTL); in mctl_sys_init()
292 writel((3 << 12) | (1 << 16), &ccm->dram_clk_cfg); in mctl_sys_init()
296 } while (readl(&ccm->dram_clk_cfg) & (1 << 16)); in mctl_sys_init()
297 setbits_le32(&ccm->dram_clk_cfg, (1 << 31)); in mctl_sys_init()
300 setbits_le32(&mctl_com->ccr, (1 << 14) | (1 << 30)); in mctl_sys_init()
301 writel(2, &mctl_com->rmcr); /* controller clock is PLL6/4 */ in mctl_sys_init()
307 if ((para->dram_clk <= 400) | ((para->dram_tpr8 & 0x1) == 0)) { in mctl_sys_init()
330 clrbits_le32(&mctl_com->ccr, MCTL_CCR_CH0_CLK_EN | MCTL_CCR_CH1_CLK_EN); in mctl_sys_init()
333 setbits_le32(&mctl_com->ccr, MCTL_CCR_CH0_CLK_EN); in mctl_sys_init()
334 /* TODO if (para->chan == 2) */ in mctl_sys_init()
335 setbits_le32(&mctl_com->ccr, MCTL_CCR_CH1_CLK_EN); in mctl_sys_init()
343 /* TODO: hard-wired for DDR3 now */ in mctl_com_init()
344 writel(((para->chan == 2) ? MCTL_CR_CHANNEL_DUAL : in mctl_com_init()
347 | MCTL_CR_ROW(para->rows) in mctl_com_init()
348 | ((para->bus_width == 32) ? MCTL_CR_BUSW32 : MCTL_CR_BUSW16) in mctl_com_init()
349 | MCTL_CR_PAGE_SIZE(para->page_size) | MCTL_CR_RANK(para->rank), in mctl_com_init()
350 &mctl_com->cr); in mctl_com_init()
352 debug("CR: %d\n", readl(&mctl_com->cr)); in mctl_com_init()
374 /* const u32 tREFI = NS2CYCLES_FLOOR(para->tREFI); */ in mctl_channel_init()
375 const u32 tREFI = NS2CYCLES_FLOOR(para->tREFI); in mctl_channel_init()
376 const u32 tRFC = NS2CYCLES_ROUNDUP(para->tRFC); in mctl_channel_init()
377 const u32 tRCD = PS2CYCLES_ROUNDUP(para->tRCD); in mctl_channel_init()
378 const u32 tRP = PS2CYCLES_ROUNDUP(para->tRP); in mctl_channel_init()
379 const u32 tRC = PS2CYCLES_ROUNDUP(para->tRC); in mctl_channel_init()
380 const u32 tRAS = PS2CYCLES_ROUNDUP(para->tRAS); in mctl_channel_init()
383 const u32 tDLLK = para->tDLLK; in mctl_channel_init()
384 const u32 tRTP = MAX(para->tRTP.ck, PS2CYCLES_ROUNDUP(para->tRTP.ps)); in mctl_channel_init()
385 const u32 tWTR = MAX(para->tWTR.ck, PS2CYCLES_ROUNDUP(para->tWTR.ps)); in mctl_channel_init()
386 const u32 tWR = NS2CYCLES_FLOOR(para->tWR); in mctl_channel_init()
387 const u32 tMRD = para->tMRD; in mctl_channel_init()
388 const u32 tMOD = MAX(para->tMOD.ck, PS2CYCLES_ROUNDUP(para->tMOD.ps)); in mctl_channel_init()
389 const u32 tCCD = para->tCCD; in mctl_channel_init()
390 const u32 tRRD = MAX(para->tRRD.ck, PS2CYCLES_ROUNDUP(para->tRRD.ps)); in mctl_channel_init()
391 const u32 tFAW = PS2CYCLES_ROUNDUP(para->tFAW); in mctl_channel_init()
394 /* const u32 tZQinit = MAX(para->tZQinit.ck, in mctl_channel_init()
395 PS2CYCLES_ROUNDUP(para->tZQinit.ps)); */ in mctl_channel_init()
396 const u32 tZQoper = MAX(para->tZQoper.ck, in mctl_channel_init()
397 PS2CYCLES_ROUNDUP(para->tZQoper.ps)); in mctl_channel_init()
398 const u32 tZQCS = MAX(para->tZQCS.ck, in mctl_channel_init()
399 PS2CYCLES_ROUNDUP(para->tZQCS.ps)); in mctl_channel_init()
402 /* const u32 tXPR = MAX(para->tXPR.ck, in mctl_channel_init()
403 PS2CYCLES_ROUNDUP(para->tXPR.ps)); */ in mctl_channel_init()
405 /* power-down timings */ in mctl_channel_init()
406 const u32 tXP = MAX(para->tXP.ck, PS2CYCLES_ROUNDUP(para->tXP.ps)); in mctl_channel_init()
407 const u32 tXPDLL = MAX(para->tXPDLL.ck, in mctl_channel_init()
408 PS2CYCLES_ROUNDUP(para->tXPDLL.ps)); in mctl_channel_init()
409 const u32 tCKE = MAX(para->tCKE.ck, PS2CYCLES_ROUNDUP(para->tCKE.ps)); in mctl_channel_init() local
412 * self-refresh timings (keep below power-down timings, as tCKESR in mctl_channel_init()
413 * needs to be calculated based on the nCK value of tCKE) in mctl_channel_init()
415 const u32 tXS = MAX(para->tXS.ck, PS2CYCLES_ROUNDUP(para->tXS.ps)); in mctl_channel_init()
416 const u32 tXSDLL = para->tXSDLL; in mctl_channel_init()
417 const u32 tCKSRE = MAX(para->tCKSRE.ck, in mctl_channel_init()
418 PS2CYCLES_ROUNDUP(para->tCKSRE.ps)); in mctl_channel_init()
419 const u32 tCKESR = tCKE + 1; in mctl_channel_init()
420 const u32 tCKSRX = MAX(para->tCKSRX.ck, in mctl_channel_init()
421 PS2CYCLES_ROUNDUP(para->tCKSRX.ps)); in mctl_channel_init()
424 const u32 tWLMRD = para->tWLMRD; in mctl_channel_init()
425 /* const u32 tWLDQSEN = para->tWLDQSEN; */ in mctl_channel_init()
426 const u32 tWLO = PS2CYCLES_FLOOR(para->tWLO); in mctl_channel_init()
427 /* const u32 tWLOE = PS2CYCLES_FLOOR(para->tWLOE); */ in mctl_channel_init()
432 for (i = 0; i < para->cl_cwl_numentries; ++i) { in mctl_channel_init()
433 const u32 tCK = 1000000 / CONFIG_DRAM_CLK; in mctl_channel_init() local
435 if ((para->cl_cwl_table[i].tCKmin <= tCK) && in mctl_channel_init()
436 (tCK < para->cl_cwl_table[i].tCKmax)) { in mctl_channel_init()
437 CL = para->cl_cwl_table[i].CL; in mctl_channel_init()
438 CWL = para->cl_cwl_table[i].CWL; in mctl_channel_init()
459 if (para->dram_type == DRAM_TYPE_DDR3) { in mctl_channel_init()
472 * Refer to Micron document "TN-41-07: DDR3 Power-Up, in mctl_channel_init()
479 &mctl_ctl->init[0]); in mctl_channel_init()
481 &mctl_ctl->init[1]); in mctl_channel_init()
484 &mctl_ctl->init[3]); in mctl_channel_init()
486 &mctl_ctl->init[4]); in mctl_channel_init()
488 &mctl_ctl->init[5]); in mctl_channel_init()
497 &mctl_ctl->init[0]); in mctl_channel_init()
499 &mctl_ctl->init[1]); in mctl_channel_init()
503 &mctl_ctl->init[2]); in mctl_channel_init()
505 &mctl_ctl->init[3]); in mctl_channel_init()
507 &mctl_ctl->init[4]); in mctl_channel_init()
512 &mctl_ctl->init[5]); in mctl_channel_init()
515 /* (DDR3) We always use a burst-length of 8. */ in mctl_channel_init()
522 * rd2wr = RL + BL/2 + 2 - WL (for DDR3) in mctl_channel_init()
523 * rd2wr = RL + BL/2 + RU(tDQSCKmax/tCK) + 1 - WL (for LPDDR2/LPDDR3) in mctl_channel_init()
525 #define RD2WR (CL + MCTL_BL/2 + 2 - CWL) in mctl_channel_init()
535 &mctl_ctl->dramtmg[0]); in mctl_channel_init()
538 &mctl_ctl->dramtmg[1]); in mctl_channel_init()
541 &mctl_ctl->dramtmg[2]); in mctl_channel_init()
547 &mctl_ctl->dramtmg[3]); in mctl_channel_init()
550 &mctl_ctl->dramtmg[4]); in mctl_channel_init()
552 (MCTL_DIV2(tCKESR) << 8) | (MCTL_DIV2(tCKE) << 0), in mctl_channel_init()
553 &mctl_ctl->dramtmg[5]); in mctl_channel_init()
557 (MCTL_TCKCSX << 0), &mctl_ctl->dramtmg[6]); */ in mctl_channel_init()
560 readl(&mctl_ctl->dramtmg[7])); */ in mctl_channel_init()
564 readl(&mctl_ctl->dramtmg[8])); */ in mctl_channel_init()
567 writel((MCTL_DIV32(tXSDLL) << 0), &mctl_ctl->dramtmg[8]); in mctl_channel_init()
570 &mctl_ctl->rfshtmg); in mctl_channel_init()
572 if (para->dram_type == DRAM_TYPE_DDR3) { in mctl_channel_init()
573 writel((2 << 24) | ((MCTL_DIV2(CL) - 2) << 16) | in mctl_channel_init()
574 (1 << 8) | ((MCTL_DIV2(CWL) - 2) << 0), in mctl_channel_init()
575 &mctl_ctl->dfitmg[0]); in mctl_channel_init()
586 clrbits_le32(&mctl_ctl->dfimisc, MCTL_DFIMISC_DFI_INIT_COMPLETE_EN); in mctl_channel_init()
588 setbits_le32(&mctl_ctl->dfiupd[0], MCTL_DFIUPD0_DIS_AUTO_CTRLUPD); in mctl_channel_init()
590 /* A80-Q7: 2T, 1 rank, DDR3, full-32bit-DQ */ in mctl_channel_init()
592 writel(MCTL_MSTR_DEVICETYPE(para->dram_type) | in mctl_channel_init()
593 MCTL_MSTR_BURSTLENGTH(para->dram_type) | in mctl_channel_init()
594 MCTL_MSTR_ACTIVERANKS(para->rank) | in mctl_channel_init()
596 &mctl_ctl->mstr); in mctl_channel_init()
598 if (para->dram_type == DRAM_TYPE_DDR3) { in mctl_channel_init()
600 (MCTL_DIV2(tZQCS)), &mctl_ctl->zqctrl[0]); in mctl_channel_init()
607 &mctl_ctl->zqctrl[1]); in mctl_channel_init()
610 &mctl_ctl->zqctrl[0]); in mctl_channel_init()
613 &mctl_ctl->zqctrl[1]); in mctl_channel_init()
617 setbits_le32(&mctl_ctl->dfimisc, MCTL_DFIMISC_DFI_INIT_COMPLETE_EN); in mctl_channel_init()
618 /* Disable auto-refresh */ in mctl_channel_init()
619 setbits_le32(&mctl_ctl->rfshctl3, MCTL_RFSHCTL3_DIS_AUTO_REFRESH); in mctl_channel_init()
623 /* TODO: make 2T and 8-bank mode configurable */ in mctl_channel_init()
626 &mctl_phy->dcr); in mctl_channel_init()
629 if (para->dram_type != DRAM_TYPE_DDR3) in mctl_channel_init()
630 clrbits_le32(&mctl_phy->dsgcr, (3 << 6)); in mctl_channel_init()
632 writel(mr[0], &mctl_phy->mr0); in mctl_channel_init()
633 writel(mr[1], &mctl_phy->mr1); in mctl_channel_init()
634 writel(mr[2], &mctl_phy->mr2); in mctl_channel_init()
635 writel(mr[3], &mctl_phy->mr3); in mctl_channel_init()
643 &mctl_phy->dtpr[0]); in mctl_channel_init()
644 writel((tMRD << 0) | ((tMOD - 12) << 2) | (tFAW << 5) | in mctl_channel_init()
646 &mctl_phy->dtpr[1]); in mctl_channel_init()
648 (tCKE << 15) | (tDLLK << 19) | in mctl_channel_init()
650 (((tCCD - 4) & 0x1) << 31), in mctl_channel_init()
651 &mctl_phy->dtpr[2]); in mctl_channel_init()
654 /* writel((tDQSCK << 0) | (tDQSCKMAX << 3), &mctl_phy->dtpr[3]); */ in mctl_channel_init()
661 writel(0x42C21590, &mctl_phy->ptr[0]); in mctl_channel_init()
662 writel(0xD05612C0, &mctl_phy->ptr[1]); in mctl_channel_init()
663 if (para->dram_type == DRAM_TYPE_DDR3) { in mctl_channel_init()
670 writel((tdinit1 << 20) | tdinit0, &mctl_phy->ptr[3]); in mctl_channel_init()
671 writel((tdinit3 << 18) | tdinit2, &mctl_phy->ptr[4]); in mctl_channel_init()
680 writel((tdinit1 << 20) | tdinit0, &mctl_phy->ptr[3]); in mctl_channel_init()
681 writel((tdinit3 << 18) | tdinit2, &mctl_phy->ptr[4]); in mctl_channel_init()
685 writel(0x00203131, &mctl_phy->acmdlr); in mctl_channel_init()
688 writel(MCTL_DTCR_DEFAULT | MCTL_DTCR_RANKEN(para->rank), in mctl_channel_init()
689 &mctl_phy->dtcr); in mctl_channel_init()
692 debug("DX2GCR0 reset: 0x%x\n", readl(&mctl_phy->dx[2].gcr[0])); in mctl_channel_init()
693 writel(0x7C000285, &mctl_phy->dx[2].gcr[0]); in mctl_channel_init()
694 writel(0x7C000285, &mctl_phy->dx[3].gcr[0]); in mctl_channel_init()
696 clrsetbits_le32(&mctl_phy->zq[0].pr, 0xff, in mctl_channel_init()
698 clrsetbits_le32(&mctl_phy->zq[1].pr, 0xff, in mctl_channel_init()
700 clrsetbits_le32(&mctl_phy->zq[2].pr, 0xff, in mctl_channel_init()
703 /* TODO: make configurable & implement non-ODT path */ in mctl_channel_init()
707 clrbits_le32(&mctl_phy->dx[lane].gcr[2], 0xffff); in mctl_channel_init()
708 clrbits_le32(&mctl_phy->dx[lane].gcr[3], in mctl_channel_init()
715 clrsetbits_le32(&mctl_phy->dx[lane].gcr[2], 0xffff, in mctl_channel_init()
717 if (para->dram_type == DRAM_TYPE_DDR3) in mctl_channel_init()
718 setbits_le32(&mctl_phy->dx[lane].gcr[3], in mctl_channel_init()
721 setbits_le32(&mctl_phy->dx[lane].gcr[3], in mctl_channel_init()
726 writel(0x04058D02, &mctl_phy->zq[0].cr); /* CK/CA */ in mctl_channel_init()
727 writel(0x04058D02, &mctl_phy->zq[1].cr); /* DX0/DX1 */ in mctl_channel_init()
728 writel(0x04058D02, &mctl_phy->zq[2].cr); /* DX2/DX3 */ in mctl_channel_init()
730 /* Disable auto-refresh prior to data training */ in mctl_channel_init()
731 setbits_le32(&mctl_ctl->rfshctl3, MCTL_RFSHCTL3_DIS_AUTO_REFRESH); in mctl_channel_init()
733 setbits_le32(&mctl_phy->dsgcr, 0xf << 24); /* unclear what this is... */ in mctl_channel_init()
734 /* TODO: IODDRM (IO DDR-MODE) for DDR3L */ in mctl_channel_init()
735 clrsetbits_le32(&mctl_phy->pgcr[1], in mctl_channel_init()
739 setbits_le32(&mctl_phy->pllcr, 0x3 << 19); /* PLL frequency select */ in mctl_channel_init()
740 /* TODO: single-channel PLL mode??? missing */ in mctl_channel_init()
741 setbits_le32(&mctl_phy->pllcr, in mctl_channel_init()
743 /* setbits_le32(&mctl_phy->pir, MCTL_PIR_PLL_BYPASS); included below */ in mctl_channel_init()
746 clrbits_le32(&mctl_phy->pgcr[0], 0x3f); in mctl_channel_init()
749 if (para->dram_type == DRAM_TYPE_DDR3) in mctl_channel_init()
750 clrsetbits_le32(&mctl_phy->pir, MCTL_PIR_MASK, 0x20df3); in mctl_channel_init()
752 clrsetbits_le32(&mctl_phy->pir, MCTL_PIR_MASK, 0x2c573); in mctl_channel_init()
757 while ((readl(&mctl_phy->pir) & MCTL_PIR_INIT) != MCTL_PIR_INIT) { in mctl_channel_init()
758 /* not done yet -- keep spinning */ in mctl_channel_init()
764 /* TODO: not used --- there's a "2rank debug" section here */ in mctl_channel_init()
769 if ((para->dram_type) == 6 || (para->dram_type) == 7) { in mctl_channel_init()
777 * Disable ZCAL after initial--for nand dma debug--20140330 by YSZ * in mctl_channel_init()
778 if (para->dram_tpr13 & (0x1<<31)) { in mctl_channel_init()
787 * TODO: more 2-rank support in mctl_channel_init()
792 if (readl(&mctl_phy->pgsr[0]) & MCTL_PGSR0_ERRORS) { in mctl_channel_init()
801 while ((readl(&mctl_ctl->stat) & 0x1) != 0x1) { in mctl_channel_init()
805 /* TODO: implement time-out */ in mctl_channel_init()
810 clrbits_le32(&mctl_phy->pgcr[3], (1 << 25)); in mctl_channel_init()
813 debug("DFIMISC before writing 0: 0x%x\n", readl(&mctl_ctl->dfimisc)); in mctl_channel_init()
814 writel(0, &mctl_ctl->dfimisc); in mctl_channel_init()
816 /* Enable auto-refresh */ in mctl_channel_init()
817 clrbits_le32(&mctl_ctl->rfshctl3, MCTL_RFSHCTL3_DIS_AUTO_REFRESH); in mctl_channel_init()
832 reg_val = readl(&mctl_com->cr); in DRAMC_get_dram_size()
835 dram_size = (temp - 6); /* (1 << dram_size) * 512Bytes */ in DRAMC_get_dram_size()
849 dram_size = dram_size - 11; /* (1 << dram_size) MBytes */ in DRAMC_get_dram_size()
911 /* self-refresh timings */ in sunxi_dram_init()
917 /* power-down timings */ in sunxi_dram_init()
920 .tCKE = { .ck = 3, .ps = 5000 }, in sunxi_dram_init()
933 * https://github.com/allwinner-zh/bootloader.git), as there in sunxi_dram_init()
945 /* dual-channel */ in sunxi_dram_init()
948 clrsetbits_le32(&mctl_com->cr, MCTL_CR_CHANNEL_MASK, in sunxi_dram_init()
951 clrbits_le32(&mctl_com->cr, MCTL_CCR_CH1_CLK_EN); in sunxi_dram_init()