uboot/drivers/ram/imxrt_sdram.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2019
   4 * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
   5 */
   6
   7#include <common.h>
   8#include <clk.h>
   9#include <dm.h>
  10#include <dm/device_compat.h>
  11#include <init.h>
  12#include <log.h>
  13#include <ram.h>
  14#include <asm/io.h>
  15#include <linux/bitops.h>
  16#include <linux/delay.h>
  17#include <linux/err.h>
  18
  19/* SDRAM Command Code */
  20#define SD_CC_ARD               0x0     /* Master Bus (AXI) command - Read */
  21#define SD_CC_AWR               0x1     /* Master Bus (AXI) command - Write */
  22#define SD_CC_IRD               0x8     /* IP command - Read */
  23#define SD_CC_IWR               0x9     /* IP command - Write */
  24#define SD_CC_IMS               0xA     /* IP command - Set Mode Register */
  25#define SD_CC_IACT              0xB     /* IP command - ACTIVE */
  26#define SD_CC_IAF               0xC     /* IP command - Auto Refresh */
  27#define SD_CC_ISF               0xD     /* IP Command - Self Refresh */
  28#define SD_CC_IPRE              0xE     /* IP command - Precharge */
  29#define SD_CC_IPREA             0xF     /* IP command - Precharge ALL */
  30
  31#define SEMC_MCR_MDIS           BIT(1)
  32#define SEMC_MCR_DQSMD          BIT(2)
  33
  34#define SEMC_INTR_IPCMDERR      BIT(1)
  35#define SEMC_INTR_IPCMDDONE     BIT(0)
  36
  37#define SEMC_IPCMD_KEY          0xA55A0000
  38
  39struct imxrt_semc_regs {
  40        /* 0x0 */
  41        u32 mcr;
  42        u32 iocr;
  43        u32 bmcr0;
  44        u32 bmcr1;
  45        u32 br[9];
  46
  47        /* 0x34 */
  48        u32 res1;
  49        u32 inten;
  50        u32 intr;
  51        /* 0x40 */
  52        u32 sdramcr0;
  53        u32 sdramcr1;
  54        u32 sdramcr2;
  55        u32 sdramcr3;
  56        /* 0x50 */
  57        u32 nandcr0;
  58        u32 nandcr1;
  59        u32 nandcr2;
  60        u32 nandcr3;
  61        /* 0x60 */
  62        u32 norcr0;
  63        u32 norcr1;
  64        u32 norcr2;
  65        u32 norcr3;
  66        /* 0x70 */
  67        u32 sramcr0;
  68        u32 sramcr1;
  69        u32 sramcr2;
  70        u32 sramcr3;
  71        /* 0x80 */
  72        u32 dbicr0;
  73        u32 dbicr1;
  74        u32 res2[2];
  75        /* 0x90 */
  76        u32 ipcr0;
  77        u32 ipcr1;
  78        u32 ipcr2;
  79        u32 ipcmd;
  80        /* 0xA0 */
  81        u32 iptxdat;
  82        u32 res3[3];
  83        /* 0xB0 */
  84        u32 iprxdat;
  85        u32 res4[3];
  86        /* 0xC0 */
  87        u32 sts[16];
  88};
  89
  90#define SEMC_IOCR_MUX_A8_SHIFT          0
  91#define SEMC_IOCR_MUX_CSX0_SHIFT        3
  92#define SEMC_IOCR_MUX_CSX1_SHIFT        6
  93#define SEMC_IOCR_MUX_CSX2_SHIFT        9
  94#define SEMC_IOCR_MUX_CSX3_SHIFT        12
  95#define SEMC_IOCR_MUX_RDY_SHIFT         15
  96
  97struct imxrt_sdram_mux {
  98        u8 a8;
  99        u8 csx0;
 100        u8 csx1;
 101        u8 csx2;
 102        u8 csx3;
 103        u8 rdy;
 104};
 105
 106#define SEMC_SDRAMCR0_PS_SHIFT          0
 107#define SEMC_SDRAMCR0_BL_SHIFT          4
 108#define SEMC_SDRAMCR0_COL_SHIFT         8
 109#define SEMC_SDRAMCR0_CL_SHIFT          10
 110
 111struct imxrt_sdram_control {
 112        u8 memory_width;
 113        u8 burst_len;
 114        u8 no_columns;
 115        u8 cas_latency;
 116};
 117
 118#define SEMC_SDRAMCR1_PRE2ACT_SHIFT     0
 119#define SEMC_SDRAMCR1_ACT2RW_SHIFT      4
 120#define SEMC_SDRAMCR1_RFRC_SHIFT        8
 121#define SEMC_SDRAMCR1_WRC_SHIFT         13
 122#define SEMC_SDRAMCR1_CKEOFF_SHIFT      16
 123#define SEMC_SDRAMCR1_ACT2PRE_SHIFT     20
 124
 125#define SEMC_SDRAMCR2_SRRC_SHIFT        0
 126#define SEMC_SDRAMCR2_REF2REF_SHIFT     8
 127#define SEMC_SDRAMCR2_ACT2ACT_SHIFT     16
 128#define SEMC_SDRAMCR2_ITO_SHIFT         24
 129
 130#define SEMC_SDRAMCR3_REN               BIT(0)
 131#define SEMC_SDRAMCR3_REBL_SHIFT        1
 132#define SEMC_SDRAMCR3_PRESCALE_SHIFT    8
 133#define SEMC_SDRAMCR3_RT_SHIFT          16
 134#define SEMC_SDRAMCR3_UT_SHIFT          24
 135
 136struct imxrt_sdram_timing {
 137        u8 pre2act;
 138        u8 act2rw;
 139        u8 rfrc;
 140        u8 wrc;
 141        u8 ckeoff;
 142        u8 act2pre;
 143
 144        u8 srrc;
 145        u8 ref2ref;
 146        u8 act2act;
 147        u8 ito;
 148
 149        u8 rebl;
 150        u8 prescale;
 151        u8 rt;
 152        u8 ut;
 153};
 154
 155enum imxrt_semc_bank {
 156        SDRAM_BANK1,
 157        SDRAM_BANK2,
 158        SDRAM_BANK3,
 159        SDRAM_BANK4,
 160        MAX_SDRAM_BANK,
 161};
 162
 163#define SEMC_BR_VLD_MASK                1
 164#define SEMC_BR_MS_SHIFT                1
 165
 166struct bank_params {
 167        enum imxrt_semc_bank target_bank;
 168        u32 base_address;
 169        u32 memory_size;
 170};
 171
 172struct imxrt_sdram_params {
 173        struct imxrt_semc_regs *base;
 174
 175        struct imxrt_sdram_mux *sdram_mux;
 176        struct imxrt_sdram_control *sdram_control;
 177        struct imxrt_sdram_timing *sdram_timing;
 178
 179        struct bank_params bank_params[MAX_SDRAM_BANK];
 180        u8 no_sdram_banks;
 181};
 182
 183static int imxrt_sdram_wait_ipcmd_done(struct imxrt_semc_regs *regs)
 184{
 185        do {
 186                readl(&regs->intr);
 187
 188                if (regs->intr & SEMC_INTR_IPCMDDONE)
 189                        return 0;
 190                if (regs->intr & SEMC_INTR_IPCMDERR)
 191                        return -EIO;
 192
 193                mdelay(50);
 194        } while (1);
 195}
 196
 197static int imxrt_sdram_ipcmd(struct imxrt_semc_regs *regs, u32 mem_addr,
 198                             u32 ipcmd, u32 wd, u32 *rd)
 199{
 200        int ret;
 201
 202        if (ipcmd == SD_CC_IWR || ipcmd == SD_CC_IMS)
 203                writel(wd, &regs->iptxdat);
 204
 205        /* set slave address for every command as specified on RM */
 206        writel(mem_addr, &regs->ipcr0);
 207
 208        /* execute command */
 209        writel(SEMC_IPCMD_KEY | ipcmd, &regs->ipcmd);
 210
 211        ret = imxrt_sdram_wait_ipcmd_done(regs);
 212        if (ret < 0)
 213                return ret;
 214
 215        if (ipcmd == SD_CC_IRD) {
 216                if (!rd)
 217                        return -EINVAL;
 218
 219                *rd = readl(&regs->iprxdat);
 220        }
 221
 222        return 0;
 223}
 224
 225int imxrt_sdram_init(struct udevice *dev)
 226{
 227        struct imxrt_sdram_params *params = dev_get_plat(dev);
 228        struct imxrt_sdram_mux *mux = params->sdram_mux;
 229        struct imxrt_sdram_control *ctrl = params->sdram_control;
 230        struct imxrt_sdram_timing *time = params->sdram_timing;
 231        struct imxrt_semc_regs *regs = params->base;
 232        struct bank_params *bank_params;
 233        u32 rd;
 234        int i;
 235
 236        /* enable the SEMC controller */
 237        clrbits_le32(&regs->mcr, SEMC_MCR_MDIS);
 238        /* set DQS mode from DQS pad */
 239        setbits_le32(&regs->mcr, SEMC_MCR_DQSMD);
 240
 241        for (i = 0, bank_params = params->bank_params;
 242                i < params->no_sdram_banks; bank_params++,
 243                i++)
 244                writel((bank_params->base_address & 0xfffff000)
 245                       | bank_params->memory_size << SEMC_BR_MS_SHIFT
 246                       | SEMC_BR_VLD_MASK,
 247                       &regs->br[bank_params->target_bank]);
 248
 249        writel(mux->a8 << SEMC_IOCR_MUX_A8_SHIFT
 250                | mux->csx0 << SEMC_IOCR_MUX_CSX0_SHIFT
 251                | mux->csx1 << SEMC_IOCR_MUX_CSX1_SHIFT
 252                | mux->csx2 << SEMC_IOCR_MUX_CSX2_SHIFT
 253                | mux->csx3 << SEMC_IOCR_MUX_CSX3_SHIFT
 254                | mux->rdy << SEMC_IOCR_MUX_RDY_SHIFT,
 255                &regs->iocr);
 256
 257        writel(ctrl->memory_width << SEMC_SDRAMCR0_PS_SHIFT
 258                | ctrl->burst_len << SEMC_SDRAMCR0_BL_SHIFT
 259                | ctrl->no_columns << SEMC_SDRAMCR0_COL_SHIFT
 260                | ctrl->cas_latency << SEMC_SDRAMCR0_CL_SHIFT,
 261                &regs->sdramcr0);
 262
 263        writel(time->pre2act << SEMC_SDRAMCR1_PRE2ACT_SHIFT
 264                | time->act2rw << SEMC_SDRAMCR1_ACT2RW_SHIFT
 265                | time->rfrc << SEMC_SDRAMCR1_RFRC_SHIFT
 266                | time->wrc << SEMC_SDRAMCR1_WRC_SHIFT
 267                | time->ckeoff << SEMC_SDRAMCR1_CKEOFF_SHIFT
 268                | time->act2pre << SEMC_SDRAMCR1_ACT2PRE_SHIFT,
 269                &regs->sdramcr1);
 270
 271        writel(time->srrc << SEMC_SDRAMCR2_SRRC_SHIFT
 272                | time->ref2ref << SEMC_SDRAMCR2_REF2REF_SHIFT
 273                | time->act2act << SEMC_SDRAMCR2_ACT2ACT_SHIFT
 274                | time->ito << SEMC_SDRAMCR2_ITO_SHIFT,
 275                &regs->sdramcr2);
 276
 277        writel(time->rebl << SEMC_SDRAMCR3_REBL_SHIFT
 278                | time->prescale << SEMC_SDRAMCR3_PRESCALE_SHIFT
 279                | time->rt << SEMC_SDRAMCR3_RT_SHIFT
 280                | time->ut << SEMC_SDRAMCR3_UT_SHIFT
 281                | SEMC_SDRAMCR3_REN,
 282                &regs->sdramcr3);
 283
 284        writel(2, &regs->ipcr1);
 285
 286        for (i = 0, bank_params = params->bank_params;
 287                i < params->no_sdram_banks; bank_params++,
 288                i++) {
 289                mdelay(250);
 290                imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IPREA,
 291                                  0, &rd);
 292                imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
 293                                  0, &rd);
 294                imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IAF,
 295                                  0, &rd);
 296                imxrt_sdram_ipcmd(regs, bank_params->base_address, SD_CC_IMS,
 297                                  ctrl->burst_len | (ctrl->cas_latency << 4),
 298                                  &rd);
 299                mdelay(250);
 300        }
 301
 302        return 0;
 303}
 304
 305static int imxrt_semc_of_to_plat(struct udevice *dev)
 306{
 307        struct imxrt_sdram_params *params = dev_get_plat(dev);
 308        ofnode bank_node;
 309        u8 bank = 0;
 310
 311        params->sdram_mux =
 312                (struct imxrt_sdram_mux *)
 313                 dev_read_u8_array_ptr(dev,
 314                                       "fsl,sdram-mux",
 315                                       sizeof(struct imxrt_sdram_mux));
 316        if (!params->sdram_mux) {
 317                pr_err("fsl,sdram-mux not found");
 318                return -EINVAL;
 319        }
 320
 321        params->sdram_control =
 322                (struct imxrt_sdram_control *)
 323                 dev_read_u8_array_ptr(dev,
 324                                       "fsl,sdram-control",
 325                                       sizeof(struct imxrt_sdram_control));
 326        if (!params->sdram_control) {
 327                pr_err("fsl,sdram-control not found");
 328                return -EINVAL;
 329        }
 330
 331        params->sdram_timing =
 332                (struct imxrt_sdram_timing *)
 333                 dev_read_u8_array_ptr(dev,
 334                                       "fsl,sdram-timing",
 335                                       sizeof(struct imxrt_sdram_timing));
 336        if (!params->sdram_timing) {
 337                pr_err("fsl,sdram-timing not found");
 338                return -EINVAL;
 339        }
 340
 341        dev_for_each_subnode(bank_node, dev) {
 342                struct bank_params *bank_params;
 343                char *bank_name;
 344                int ret;
 345
 346                /* extract the bank index from DT */
 347                bank_name = (char *)ofnode_get_name(bank_node);
 348                strsep(&bank_name, "@");
 349                if (!bank_name) {
 350                        pr_err("missing sdram bank index");
 351                        return -EINVAL;
 352                }
 353
 354                bank_params = &params->bank_params[bank];
 355                strict_strtoul(bank_name, 10,
 356                               (unsigned long *)&bank_params->target_bank);
 357                if (bank_params->target_bank >= MAX_SDRAM_BANK) {
 358                        pr_err("Found bank %d , but only bank 0,1,2,3 are supported",
 359                               bank_params->target_bank);
 360                        return -EINVAL;
 361                }
 362
 363                ret = ofnode_read_u32(bank_node,
 364                                      "fsl,memory-size",
 365                                      &bank_params->memory_size);
 366                if (ret < 0) {
 367                        pr_err("fsl,memory-size not found");
 368                        return -EINVAL;
 369                }
 370
 371                ret = ofnode_read_u32(bank_node,
 372                                      "fsl,base-address",
 373                                      &bank_params->base_address);
 374                if (ret < 0) {
 375                        pr_err("fsl,base-address not found");
 376                        return -EINVAL;
 377                }
 378
 379                debug("Found bank %s %u\n", bank_name,
 380                      bank_params->target_bank);
 381                bank++;
 382        }
 383
 384        params->no_sdram_banks = bank;
 385        debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
 386
 387        return 0;
 388}
 389
 390static int imxrt_semc_probe(struct udevice *dev)
 391{
 392        struct imxrt_sdram_params *params = dev_get_plat(dev);
 393        int ret;
 394        fdt_addr_t addr;
 395
 396        addr = dev_read_addr(dev);
 397        if (addr == FDT_ADDR_T_NONE)
 398                return -EINVAL;
 399
 400        params->base = (struct imxrt_semc_regs *)addr;
 401
 402#ifdef CONFIG_CLK
 403        struct clk clk;
 404
 405        ret = clk_get_by_index(dev, 0, &clk);
 406        if (ret < 0)
 407                return ret;
 408
 409        ret = clk_enable(&clk);
 410
 411        if (ret) {
 412                dev_err(dev, "failed to enable clock\n");
 413                return ret;
 414        }
 415#endif
 416        ret = imxrt_sdram_init(dev);
 417        if (ret)
 418                return ret;
 419
 420        return 0;
 421}
 422
 423static int imxrt_semc_get_info(struct udevice *dev, struct ram_info *info)
 424{
 425        return 0;
 426}
 427
 428static struct ram_ops imxrt_semc_ops = {
 429        .get_info = imxrt_semc_get_info,
 430};
 431
 432static const struct udevice_id imxrt_semc_ids[] = {
 433        { .compatible = "fsl,imxrt-semc", .data = 0 },
 434        { }
 435};
 436
 437U_BOOT_DRIVER(imxrt_semc) = {
 438        .name = "imxrt_semc",
 439        .id = UCLASS_RAM,
 440        .of_match = imxrt_semc_ids,
 441        .ops = &imxrt_semc_ops,
 442        .of_to_plat = imxrt_semc_of_to_plat,
 443        .probe = imxrt_semc_probe,
 444        .plat_auto      = sizeof(struct imxrt_sdram_params),
 445};
 446