uboot/arch/mips/mach-jz47xx/jz4780/sdram.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * JZ4780 DDR initialization
   4 *
   5 * Copyright (c) 2013 Imagination Technologies
   6 * Author: Paul Burton <paul.burton@imgtec.com>
   7 *
   8 * Based on spl/common/{jz4780_ddr,jz_ddr3_init}.c from X-Boot
   9 * Copyright (c) 2006-2013 Ingenic Semiconductor
  10 */
  11
  12#include <common.h>
  13#include <hang.h>
  14#include <init.h>
  15#include <asm/io.h>
  16#include <linux/bitops.h>
  17#include <linux/delay.h>
  18#include <mach/jz4780.h>
  19#include <mach/jz4780_dram.h>
  20
  21static const u32 get_mem_clk(void)
  22{
  23        const u32 mpll_out = ((u64)JZ4780_SYS_EXTAL * JZ4780_MPLL_M) /
  24                             (JZ4780_MPLL_N * JZ4780_MPLL_OD);
  25        return mpll_out / JZ4780_SYS_MEM_DIV;
  26}
  27
  28u32 sdram_size(int cs)
  29{
  30        u32 dw = DDR_DW32 ? 4 : 2;
  31        u32 banks = DDR_BANK8 ? 8 : 4;
  32        u32 size = 0;
  33
  34        if ((cs == 0) && DDR_CS0EN) {
  35                size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
  36                if (DDR_CS1EN && (size > 0x20000000))
  37                        size = 0x20000000;
  38        } else if ((cs == 1) && DDR_CS1EN) {
  39                size = (1 << (DDR_ROW + DDR_COL)) * dw * banks;
  40        }
  41
  42        return size;
  43}
  44
  45static void ddr_cfg_init(void)
  46{
  47        void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
  48        u32 ddrc_cfg, tmp;
  49
  50        tmp = DDR_CL;
  51        if (tmp)
  52                tmp--;
  53        if (tmp > 4)
  54                tmp = 4;
  55
  56        ddrc_cfg = DDRC_CFG_TYPE_DDR3 | DDRC_CFG_IMBA |
  57                   DDR_DW32 | DDRC_CFG_MPRT | ((tmp | 0x8) << 2) |
  58                   ((DDR_ROW - 12) << 11) | ((DDR_COL - 8) << 8) |
  59                   (DDR_CS0EN << 6) | (DDR_BANK8 << 1) |
  60                   ((DDR_ROW - 12) << 27) | ((DDR_COL - 8) << 24) |
  61                   (DDR_CS1EN << 7) | (DDR_BANK8 << 23);
  62
  63        if (DDR_BL > 4)
  64                ddrc_cfg |= BIT(21);
  65
  66        writel(ddrc_cfg, ddr_ctl_regs + DDRC_CFG);
  67}
  68
  69static void ddr_phy_init(const struct jz4780_ddr_config *ddr_config)
  70{
  71        void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
  72        void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
  73        unsigned int count = 0, i;
  74        u32 reg, mask;
  75
  76        writel(DDRP_DCR_TYPE_DDR3 | (DDR_BANK8 << 3), ddr_phy_regs + DDRP_DCR);
  77
  78        writel(ddr_config->mr0, ddr_phy_regs + DDRP_MR0);
  79        writel(ddr_config->mr1, ddr_phy_regs + DDRP_MR1);
  80        writel(0, ddr_phy_regs + DDRP_ODTCR);
  81        writel(0, ddr_phy_regs + DDRP_MR2);
  82
  83        writel(ddr_config->ptr0, ddr_phy_regs + DDRP_PTR0);
  84        writel(ddr_config->ptr1, ddr_phy_regs + DDRP_PTR1);
  85        writel(ddr_config->ptr2, ddr_phy_regs + DDRP_PTR2);
  86
  87        writel(ddr_config->dtpr0, ddr_phy_regs + DDRP_DTPR0);
  88        writel(ddr_config->dtpr1, ddr_phy_regs + DDRP_DTPR1);
  89        writel(ddr_config->dtpr2, ddr_phy_regs + DDRP_DTPR2);
  90
  91        writel(DDRP_PGCR_DQSCFG | (7 << DDRP_PGCR_CKEN_BIT) |
  92               (2 << DDRP_PGCR_CKDV_BIT) |
  93               (DDR_CS0EN | (DDR_CS1EN << 1)) << DDRP_PGCR_RANKEN_BIT |
  94               DDRP_PGCR_ZCKSEL_32 | DDRP_PGCR_PDDISDX,
  95               ddr_phy_regs + DDRP_PGCR);
  96
  97        for (i = 0; i < 8; i++)
  98                clrbits_le32(ddr_phy_regs + DDRP_DXGCR(i), 0x3 << 9);
  99
 100        count = 0;
 101        mask = DDRP_PGSR_IDONE | DDRP_PGSR_DLDONE | DDRP_PGSR_ZCDONE;
 102        for (;;) {
 103                reg = readl(ddr_phy_regs + DDRP_PGSR);
 104                if ((reg == mask) || (reg == 0x1f))
 105                        break;
 106                if (count++ == 10000)
 107                        hang();
 108        }
 109
 110        /* DQS extension and early set to 1 */
 111        clrsetbits_le32(ddr_phy_regs + DDRP_DSGCR, 0x7E << 4, 0x12 << 4);
 112
 113        /* 500 pull up and 500 pull down */
 114        clrsetbits_le32(ddr_phy_regs + DDRP_DXCCR, 0xFF << 4, 0xC4 << 4);
 115
 116        /* Initialise phy */
 117        writel(DDRP_PIR_INIT | DDRP_PIR_DRAMINT | DDRP_PIR_DRAMRST,
 118               ddr_phy_regs + DDRP_PIR);
 119
 120        count = 0;
 121        mask |= DDRP_PGSR_DIDONE;
 122        for (;;) {
 123                reg = readl(ddr_phy_regs + DDRP_PGSR);
 124                if ((reg == mask) || (reg == 0x1f))
 125                        break;
 126                if (count++ == 20000)
 127                        hang();
 128        }
 129
 130        writel(DDRP_PIR_INIT | DDRP_PIR_QSTRN, ddr_phy_regs + DDRP_PIR);
 131
 132        count = 0;
 133        mask |= DDRP_PGSR_DTDONE;
 134        for (;;) {
 135                reg = readl(ddr_phy_regs + DDRP_PGSR);
 136                if (reg == mask)
 137                        break;
 138                if (count++ != 50000)
 139                        continue;
 140                reg &= DDRP_PGSR_DTDONE | DDRP_PGSR_DTERR | DDRP_PGSR_DTIERR;
 141                if (reg)
 142                        hang();
 143                count = 0;
 144        }
 145
 146        /* Override impedance */
 147        clrsetbits_le32(ddr_phy_regs + DDRP_ZQXCR0(0), 0x3ff,
 148                ((ddr_config->pullup & 0x1f) << DDRP_ZQXCR_PULLUP_IMPE_BIT) |
 149                ((ddr_config->pulldn & 0x1f) << DDRP_ZQXCR_PULLDOWN_IMPE_BIT) |
 150                DDRP_ZQXCR_ZDEN);
 151}
 152
 153#define JZBIT(bit) ((bit % 4) * 8)
 154#define JZMASK(bit) (0x1f << JZBIT(bit))
 155
 156static void remap_swap(int a, int b)
 157{
 158        void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
 159        u32 remmap[2], tmp[2];
 160
 161        remmap[0] = readl(ddr_ctl_regs + DDRC_REMMAP(a / 4));
 162        remmap[1] = readl(ddr_ctl_regs + DDRC_REMMAP(b / 4));
 163
 164        tmp[0] = (remmap[0] & JZMASK(a)) >> JZBIT(a);
 165        tmp[1] = (remmap[1] & JZMASK(b)) >> JZBIT(b);
 166
 167        remmap[0] &= ~JZMASK(a);
 168        remmap[1] &= ~JZMASK(b);
 169
 170        writel(remmap[0] | (tmp[1] << JZBIT(a)),
 171               ddr_ctl_regs + DDRC_REMMAP(a / 4));
 172        writel(remmap[1] | (tmp[0] << JZBIT(b)),
 173               ddr_ctl_regs + DDRC_REMMAP(b / 4));
 174}
 175
 176static void mem_remap(void)
 177{
 178        u32 start = (DDR_ROW + DDR_COL + (DDR_DW32 ? 4 : 2) / 2) - 12;
 179        u32 num = DDR_BANK8 ? 3 : 2;
 180
 181        if (DDR_CS0EN && DDR_CS1EN)
 182                num++;
 183
 184        for (; num > 0; num--)
 185                remap_swap(0 + num - 1, start + num - 1);
 186}
 187
 188/* Fetch DRAM config from board file */
 189__weak const struct jz4780_ddr_config *jz4780_get_ddr_config(void)
 190{
 191        return NULL;
 192}
 193
 194void sdram_init(void)
 195{
 196        const struct jz4780_ddr_config *ddr_config = jz4780_get_ddr_config();
 197        void __iomem *ddr_ctl_regs = (void __iomem *)DDRC_BASE;
 198        void __iomem *ddr_phy_regs = ddr_ctl_regs + DDR_PHY_OFFSET;
 199        void __iomem *cpm_regs = (void __iomem *)CPM_BASE;
 200        u32 mem_clk, tmp, i;
 201        u32 mem_base0, mem_base1;
 202        u32 mem_mask0, mem_mask1;
 203        u32 mem_size0, mem_size1;
 204
 205        if (!ddr_config)
 206                hang();
 207
 208        /* Reset DLL in DDR PHY */
 209        writel(0x3, cpm_regs + 0xd0);
 210        mdelay(400);
 211        writel(0x1, cpm_regs + 0xd0);
 212        mdelay(400);
 213
 214        /* Enter reset */
 215        writel(0xf << 20, ddr_ctl_regs + DDRC_CTRL);
 216
 217        mem_clk = get_mem_clk();
 218
 219        tmp = 1000000000 / mem_clk;
 220        if (1000000000 % mem_clk)
 221                tmp++;
 222        tmp = DDR_tREFI / tmp;
 223        tmp = tmp / (16 * (1 << DDR_CLK_DIV)) - 1;
 224        if (tmp > 0xff)
 225                tmp = 0xff;
 226        if (tmp < 1)
 227                tmp = 1;
 228
 229        writel(0x0, ddr_ctl_regs + DDRC_CTRL);
 230
 231        writel(0x150000, ddr_phy_regs + DDRP_DTAR);
 232        ddr_phy_init(ddr_config);
 233
 234        writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
 235        writel(0x0, ddr_ctl_regs + DDRC_CTRL);
 236
 237        ddr_cfg_init();
 238
 239        for (i = 0; i < 6; i++)
 240                writel(ddr_config->timing[i], ddr_ctl_regs + DDRC_TIMING(i));
 241
 242        mem_size0 = sdram_size(0);
 243        mem_size1 = sdram_size(1);
 244
 245        if (!mem_size1 && mem_size0 > 0x20000000) {
 246                mem_base0 = 0x0;
 247                mem_mask0 = ~(((mem_size0 * 2) >> 24) - 1) & DDRC_MMAP_MASK_MASK;
 248        } else {
 249                mem_base0 = (DDR_MEM_PHY_BASE >> 24) & 0xff;
 250                mem_mask0 = ~((mem_size0 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
 251        }
 252
 253        if (mem_size1) {
 254                mem_mask1 = ~((mem_size1 >> 24) - 1) & DDRC_MMAP_MASK_MASK;
 255                mem_base1 = ((DDR_MEM_PHY_BASE + mem_size0) >> 24) & 0xff;
 256        } else {
 257                mem_mask1 = 0;
 258                mem_base1 = 0xff;
 259        }
 260
 261        writel(mem_base0 << DDRC_MMAP_BASE_BIT | mem_mask0,
 262               ddr_ctl_regs + DDRC_MMAP0);
 263        writel(mem_base1 << DDRC_MMAP_BASE_BIT | mem_mask1,
 264               ddr_ctl_regs + DDRC_MMAP1);
 265        writel(DDRC_CTRL_CKE | DDRC_CTRL_ALH, ddr_ctl_regs + DDRC_CTRL);
 266        writel((DDR_CLK_DIV << 1) | DDRC_REFCNT_REF_EN |
 267               (tmp << DDRC_REFCNT_CON_BIT),
 268               ddr_ctl_regs + DDRC_REFCNT);
 269        writel((1 << 15) | (4 << 12) | (1 << 11) | (1 << 8) | (0 << 6) |
 270               (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1),
 271               ddr_ctl_regs + DDRC_CTRL);
 272        mem_remap();
 273        clrbits_le32(ddr_ctl_regs + DDRC_ST, 0x40);
 274}
 275