uboot/drivers/ram/k3-ddrss/k3-ddrss.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Texas Instruments' K3 DDRSS driver
   4 *
   5 * Copyright (C) 2020-2021 Texas Instruments Incorporated - http://www.ti.com/
   6 */
   7
   8#include <common.h>
   9#include <clk.h>
  10#include <dm.h>
  11#include <dm/device_compat.h>
  12#include <ram.h>
  13#include <hang.h>
  14#include <log.h>
  15#include <asm/io.h>
  16#include <power-domain.h>
  17#include <wait_bit.h>
  18#include <power/regulator.h>
  19
  20#include "lpddr4_obj_if.h"
  21#include "lpddr4_if.h"
  22#include "lpddr4_structs_if.h"
  23#include "lpddr4_ctl_regs.h"
  24
  25#define SRAM_MAX 512
  26
  27#define CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS       0x80
  28#define CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS       0xc0
  29
  30#define DDRSS_V2A_R1_MAT_REG                    0x0020
  31#define DDRSS_ECC_CTRL_REG                      0x0120
  32
  33struct k3_ddrss_desc {
  34        struct udevice *dev;
  35        void __iomem *ddrss_ss_cfg;
  36        void __iomem *ddrss_ctrl_mmr;
  37        struct power_domain ddrcfg_pwrdmn;
  38        struct power_domain ddrdata_pwrdmn;
  39        struct clk ddr_clk;
  40        struct clk osc_clk;
  41        u32 ddr_freq1;
  42        u32 ddr_freq2;
  43        u32 ddr_fhs_cnt;
  44        struct udevice *vtt_supply;
  45};
  46
  47static lpddr4_obj *driverdt;
  48static lpddr4_config config;
  49static lpddr4_privatedata pd;
  50
  51static struct k3_ddrss_desc *ddrss;
  52
  53struct reginitdata {
  54        u32 ctl_regs[LPDDR4_INTR_CTL_REG_COUNT];
  55        u16 ctl_regs_offs[LPDDR4_INTR_CTL_REG_COUNT];
  56        u32 pi_regs[LPDDR4_INTR_PHY_INDEP_REG_COUNT];
  57        u16 pi_regs_offs[LPDDR4_INTR_PHY_INDEP_REG_COUNT];
  58        u32 phy_regs[LPDDR4_INTR_PHY_REG_COUNT];
  59        u16 phy_regs_offs[LPDDR4_INTR_PHY_REG_COUNT];
  60};
  61
  62#define TH_MACRO_EXP(fld, str) (fld##str)
  63
  64#define TH_FLD_MASK(fld)  TH_MACRO_EXP(fld, _MASK)
  65#define TH_FLD_SHIFT(fld) TH_MACRO_EXP(fld, _SHIFT)
  66#define TH_FLD_WIDTH(fld) TH_MACRO_EXP(fld, _WIDTH)
  67#define TH_FLD_WOCLR(fld) TH_MACRO_EXP(fld, _WOCLR)
  68#define TH_FLD_WOSET(fld) TH_MACRO_EXP(fld, _WOSET)
  69
  70#define str(s) #s
  71#define xstr(s) str(s)
  72
  73#define CTL_SHIFT 11
  74#define PHY_SHIFT 11
  75#define PI_SHIFT 10
  76
  77#define DENALI_CTL_0_DRAM_CLASS_DDR4            0xA
  78#define DENALI_CTL_0_DRAM_CLASS_LPDDR4          0xB
  79
  80#define TH_OFFSET_FROM_REG(REG, SHIFT, offset) do {\
  81        char *i, *pstr = xstr(REG); offset = 0;\
  82        for (i = &pstr[SHIFT]; *i != '\0'; ++i) {\
  83                offset = offset * 10 + (*i - '0'); } \
  84        } while (0)
  85
  86static u32 k3_lpddr4_read_ddr_type(void)
  87{
  88        u32 status = 0U;
  89        u32 offset = 0U;
  90        u32 regval = 0U;
  91        u32 dram_class = 0U;
  92
  93        TH_OFFSET_FROM_REG(LPDDR4__DRAM_CLASS__REG, CTL_SHIFT, offset);
  94        status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
  95        if (status > 0U) {
  96                printf("%s: Failed to read DRAM_CLASS\n", __func__);
  97                hang();
  98        }
  99
 100        dram_class = ((regval & TH_FLD_MASK(LPDDR4__DRAM_CLASS__FLD)) >>
 101                TH_FLD_SHIFT(LPDDR4__DRAM_CLASS__FLD));
 102        return dram_class;
 103}
 104
 105static void k3_lpddr4_freq_update(void)
 106{
 107        unsigned int req_type, counter;
 108
 109        for (counter = 0; counter < ddrss->ddr_fhs_cnt; counter++) {
 110                if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
 111                                      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
 112                                      true, 10000, false)) {
 113                        printf("Timeout during frequency handshake\n");
 114                        hang();
 115                }
 116
 117                req_type = readl(ddrss->ddrss_ctrl_mmr +
 118                                 CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS) & 0x03;
 119
 120                debug("%s: received freq change req: req type = %d, req no. = %d\n",
 121                      __func__, req_type, counter);
 122
 123                if (req_type == 1)
 124                        clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
 125                else if (req_type == 2)
 126                        clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq2);
 127                else if (req_type == 0)
 128                        /* Put DDR pll in bypass mode */
 129                        clk_set_rate(&ddrss->ddr_clk,
 130                                     clk_get_rate(&ddrss->osc_clk));
 131                else
 132                        printf("%s: Invalid freq request type\n", __func__);
 133
 134                writel(0x1, ddrss->ddrss_ctrl_mmr +
 135                       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
 136                if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
 137                                      CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
 138                                      false, 10, false)) {
 139                        printf("Timeout during frequency handshake\n");
 140                        hang();
 141                }
 142                writel(0x0, ddrss->ddrss_ctrl_mmr +
 143                       CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
 144        }
 145}
 146
 147static void k3_lpddr4_ack_freq_upd_req(void)
 148{
 149        u32 dram_class;
 150
 151        debug("--->>> LPDDR4 Initialization is in progress ... <<<---\n");
 152
 153        dram_class = k3_lpddr4_read_ddr_type();
 154
 155        switch (dram_class) {
 156        case DENALI_CTL_0_DRAM_CLASS_DDR4:
 157                break;
 158        case DENALI_CTL_0_DRAM_CLASS_LPDDR4:
 159                k3_lpddr4_freq_update();
 160                break;
 161        default:
 162                printf("Unrecognized dram_class cannot update frequency!\n");
 163        }
 164}
 165
 166static int k3_ddrss_init_freq(struct k3_ddrss_desc *ddrss)
 167{
 168        u32 dram_class;
 169        int ret;
 170
 171        dram_class = k3_lpddr4_read_ddr_type();
 172
 173        switch (dram_class) {
 174        case DENALI_CTL_0_DRAM_CLASS_DDR4:
 175                /* Set to ddr_freq1 from DT for DDR4 */
 176                ret = clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
 177                break;
 178        case DENALI_CTL_0_DRAM_CLASS_LPDDR4:
 179                /* Set to bypass frequency for LPDDR4*/
 180                ret = clk_set_rate(&ddrss->ddr_clk, clk_get_rate(&ddrss->osc_clk));
 181                break;
 182        default:
 183                ret = -EINVAL;
 184                printf("Unrecognized dram_class cannot init frequency!\n");
 185        }
 186
 187        if (ret < 0)
 188                dev_err(ddrss->dev, "ddr clk init failed: %d\n", ret);
 189        else
 190                ret = 0;
 191
 192        return ret;
 193}
 194
 195static void k3_lpddr4_info_handler(const lpddr4_privatedata *pd,
 196                                   lpddr4_infotype infotype)
 197{
 198        if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE)
 199                k3_lpddr4_ack_freq_upd_req();
 200}
 201
 202static int k3_ddrss_power_on(struct k3_ddrss_desc *ddrss)
 203{
 204        int ret;
 205
 206        debug("%s(ddrss=%p)\n", __func__, ddrss);
 207
 208        ret = power_domain_on(&ddrss->ddrcfg_pwrdmn);
 209        if (ret) {
 210                dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
 211                return ret;
 212        }
 213
 214        ret = power_domain_on(&ddrss->ddrdata_pwrdmn);
 215        if (ret) {
 216                dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
 217                return ret;
 218        }
 219
 220        ret = device_get_supply_regulator(ddrss->dev, "vtt-supply",
 221                                          &ddrss->vtt_supply);
 222        if (ret) {
 223                dev_dbg(ddrss->dev, "vtt-supply not found.\n");
 224        } else {
 225                ret = regulator_set_value(ddrss->vtt_supply, 3300000);
 226                if (ret)
 227                        return ret;
 228                dev_dbg(ddrss->dev, "VTT regulator enabled, volt = %d\n",
 229                        regulator_get_value(ddrss->vtt_supply));
 230        }
 231
 232        return 0;
 233}
 234
 235static int k3_ddrss_ofdata_to_priv(struct udevice *dev)
 236{
 237        struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
 238        phys_addr_t reg;
 239        int ret;
 240
 241        debug("%s(dev=%p)\n", __func__, dev);
 242
 243        reg = dev_read_addr_name(dev, "cfg");
 244        if (reg == FDT_ADDR_T_NONE) {
 245                dev_err(dev, "No reg property for DDRSS wrapper logic\n");
 246                return -EINVAL;
 247        }
 248        ddrss->ddrss_ss_cfg = (void *)reg;
 249
 250        reg = dev_read_addr_name(dev, "ctrl_mmr_lp4");
 251        if (reg == FDT_ADDR_T_NONE) {
 252                dev_err(dev, "No reg property for CTRL MMR\n");
 253                return -EINVAL;
 254        }
 255        ddrss->ddrss_ctrl_mmr = (void *)reg;
 256
 257        ret = power_domain_get_by_index(dev, &ddrss->ddrcfg_pwrdmn, 0);
 258        if (ret) {
 259                dev_err(dev, "power_domain_get() failed: %d\n", ret);
 260                return ret;
 261        }
 262
 263        ret = power_domain_get_by_index(dev, &ddrss->ddrdata_pwrdmn, 1);
 264        if (ret) {
 265                dev_err(dev, "power_domain_get() failed: %d\n", ret);
 266                return ret;
 267        }
 268
 269        ret = clk_get_by_index(dev, 0, &ddrss->ddr_clk);
 270        if (ret)
 271                dev_err(dev, "clk get failed%d\n", ret);
 272
 273        ret = clk_get_by_index(dev, 1, &ddrss->osc_clk);
 274        if (ret)
 275                dev_err(dev, "clk get failed for osc clk %d\n", ret);
 276
 277        ret = dev_read_u32(dev, "ti,ddr-freq1", &ddrss->ddr_freq1);
 278        if (ret)
 279                dev_err(dev, "ddr freq1 not populated %d\n", ret);
 280
 281        ret = dev_read_u32(dev, "ti,ddr-freq2", &ddrss->ddr_freq2);
 282        if (ret)
 283                dev_err(dev, "ddr freq2 not populated %d\n", ret);
 284
 285        ret = dev_read_u32(dev, "ti,ddr-fhs-cnt", &ddrss->ddr_fhs_cnt);
 286        if (ret)
 287                dev_err(dev, "ddr fhs cnt not populated %d\n", ret);
 288
 289        return ret;
 290}
 291
 292void k3_lpddr4_probe(void)
 293{
 294        u32 status = 0U;
 295        u16 configsize = 0U;
 296
 297        status = driverdt->probe(&config, &configsize);
 298
 299        if ((status != 0) || (configsize != sizeof(lpddr4_privatedata))
 300            || (configsize > SRAM_MAX)) {
 301                printf("%s: FAIL\n", __func__);
 302                hang();
 303        } else {
 304                debug("%s: PASS\n", __func__);
 305        }
 306}
 307
 308void k3_lpddr4_init(void)
 309{
 310        u32 status = 0U;
 311
 312        if ((sizeof(pd) != sizeof(lpddr4_privatedata))
 313            || (sizeof(pd) > SRAM_MAX)) {
 314                printf("%s: FAIL\n", __func__);
 315                hang();
 316        }
 317
 318        config.ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
 319        config.infohandler = (lpddr4_infocallback) k3_lpddr4_info_handler;
 320
 321        status = driverdt->init(&pd, &config);
 322
 323        if ((status > 0U) ||
 324            (pd.ctlbase != (struct lpddr4_ctlregs_s *)config.ctlbase) ||
 325            (pd.ctlinterrupthandler != config.ctlinterrupthandler) ||
 326            (pd.phyindepinterrupthandler != config.phyindepinterrupthandler)) {
 327                printf("%s: FAIL\n", __func__);
 328                hang();
 329        } else {
 330                debug("%s: PASS\n", __func__);
 331        }
 332}
 333
 334void populate_data_array_from_dt(struct reginitdata *reginit_data)
 335{
 336        int ret, i;
 337
 338        ret = dev_read_u32_array(ddrss->dev, "ti,ctl-data",
 339                                 (u32 *)reginit_data->ctl_regs,
 340                                 LPDDR4_INTR_CTL_REG_COUNT);
 341        if (ret)
 342                printf("Error reading ctrl data %d\n", ret);
 343
 344        for (i = 0; i < LPDDR4_INTR_CTL_REG_COUNT; i++)
 345                reginit_data->ctl_regs_offs[i] = i;
 346
 347        ret = dev_read_u32_array(ddrss->dev, "ti,pi-data",
 348                                 (u32 *)reginit_data->pi_regs,
 349                                 LPDDR4_INTR_PHY_INDEP_REG_COUNT);
 350        if (ret)
 351                printf("Error reading PI data\n");
 352
 353        for (i = 0; i < LPDDR4_INTR_PHY_INDEP_REG_COUNT; i++)
 354                reginit_data->pi_regs_offs[i] = i;
 355
 356        ret = dev_read_u32_array(ddrss->dev, "ti,phy-data",
 357                                 (u32 *)reginit_data->phy_regs,
 358                                 LPDDR4_INTR_PHY_REG_COUNT);
 359        if (ret)
 360                printf("Error reading PHY data %d\n", ret);
 361
 362        for (i = 0; i < LPDDR4_INTR_PHY_REG_COUNT; i++)
 363                reginit_data->phy_regs_offs[i] = i;
 364}
 365
 366void k3_lpddr4_hardware_reg_init(void)
 367{
 368        u32 status = 0U;
 369        struct reginitdata reginitdata;
 370
 371        populate_data_array_from_dt(&reginitdata);
 372
 373        status = driverdt->writectlconfig(&pd, reginitdata.ctl_regs,
 374                                          reginitdata.ctl_regs_offs,
 375                                          LPDDR4_INTR_CTL_REG_COUNT);
 376        if (!status)
 377                status = driverdt->writephyindepconfig(&pd, reginitdata.pi_regs,
 378                                                       reginitdata.pi_regs_offs,
 379                                                       LPDDR4_INTR_PHY_INDEP_REG_COUNT);
 380        if (!status)
 381                status = driverdt->writephyconfig(&pd, reginitdata.phy_regs,
 382                                                  reginitdata.phy_regs_offs,
 383                                                  LPDDR4_INTR_PHY_REG_COUNT);
 384        if (status) {
 385                printf("%s: FAIL\n", __func__);
 386                hang();
 387        }
 388}
 389
 390void k3_lpddr4_start(void)
 391{
 392        u32 status = 0U;
 393        u32 regval = 0U;
 394        u32 offset = 0U;
 395
 396        TH_OFFSET_FROM_REG(LPDDR4__START__REG, CTL_SHIFT, offset);
 397
 398        status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
 399        if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 0U)) {
 400                printf("%s: Pre start FAIL\n", __func__);
 401                hang();
 402        }
 403
 404        status = driverdt->start(&pd);
 405        if (status > 0U) {
 406                printf("%s: FAIL\n", __func__);
 407                hang();
 408        }
 409
 410        status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
 411        if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 1U)) {
 412                printf("%s: Post start FAIL\n", __func__);
 413                hang();
 414        } else {
 415                debug("%s: Post start PASS\n", __func__);
 416        }
 417}
 418
 419static int k3_ddrss_probe(struct udevice *dev)
 420{
 421        int ret;
 422
 423        ddrss = dev_get_priv(dev);
 424
 425        debug("%s(dev=%p)\n", __func__, dev);
 426
 427        ret = k3_ddrss_ofdata_to_priv(dev);
 428        if (ret)
 429                return ret;
 430
 431        ddrss->dev = dev;
 432        ret = k3_ddrss_power_on(ddrss);
 433        if (ret)
 434                return ret;
 435
 436#ifdef CONFIG_K3_AM64_DDRSS
 437
 438        writel(0x000001EF, ddrss->ddrss_ss_cfg + DDRSS_V2A_R1_MAT_REG);
 439        writel(0x0, ddrss->ddrss_ss_cfg + DDRSS_ECC_CTRL_REG);
 440#endif
 441
 442        driverdt = lpddr4_getinstance();
 443        k3_lpddr4_probe();
 444        k3_lpddr4_init();
 445        k3_lpddr4_hardware_reg_init();
 446
 447        ret = k3_ddrss_init_freq(ddrss);
 448        if (ret)
 449                return ret;
 450
 451        k3_lpddr4_start();
 452
 453        return ret;
 454}
 455
 456static int k3_ddrss_get_info(struct udevice *dev, struct ram_info *info)
 457{
 458        return 0;
 459}
 460
 461static struct ram_ops k3_ddrss_ops = {
 462        .get_info = k3_ddrss_get_info,
 463};
 464
 465static const struct udevice_id k3_ddrss_ids[] = {
 466        {.compatible = "ti,am64-ddrss"},
 467        {.compatible = "ti,j721e-ddrss"},
 468        {}
 469};
 470
 471U_BOOT_DRIVER(k3_ddrss) = {
 472        .name                   = "k3_ddrss",
 473        .id                     = UCLASS_RAM,
 474        .of_match               = k3_ddrss_ids,
 475        .ops                    = &k3_ddrss_ops,
 476        .probe                  = k3_ddrss_probe,
 477        .priv_auto              = sizeof(struct k3_ddrss_desc),
 478};
 479