k3-j721e-ddrss.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Texas Instruments' J721E DDRSS driver
  4. *
  5. * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
  6. */
  7. #include <common.h>
  8. #include <clk.h>
  9. #include <dm.h>
  10. #include <hang.h>
  11. #include <log.h>
  12. #include <ram.h>
  13. #include <asm/io.h>
  14. #include <power-domain.h>
  15. #include <wait_bit.h>
  16. #include <dm/device_compat.h>
  17. #include "lpddr4_obj_if.h"
  18. #include "lpddr4_if.h"
  19. #include "lpddr4_structs_if.h"
  20. #include "lpddr4_ctl_regs.h"
  21. #define SRAM_MAX 512
  22. #define CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS 0x80
  23. #define CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS 0xc0
  24. struct j721e_ddrss_desc {
  25. struct udevice *dev;
  26. void __iomem *ddrss_ss_cfg;
  27. void __iomem *ddrss_ctrl_mmr;
  28. struct power_domain ddrcfg_pwrdmn;
  29. struct power_domain ddrdata_pwrdmn;
  30. struct clk ddr_clk;
  31. struct clk osc_clk;
  32. u32 ddr_freq1;
  33. u32 ddr_freq2;
  34. u32 ddr_fhs_cnt;
  35. };
  36. static LPDDR4_OBJ *driverdt;
  37. static lpddr4_config config;
  38. static lpddr4_privatedata pd;
  39. static struct j721e_ddrss_desc *ddrss;
  40. #define TH_MACRO_EXP(fld, str) (fld##str)
  41. #define TH_FLD_MASK(fld) TH_MACRO_EXP(fld, _MASK)
  42. #define TH_FLD_SHIFT(fld) TH_MACRO_EXP(fld, _SHIFT)
  43. #define TH_FLD_WIDTH(fld) TH_MACRO_EXP(fld, _WIDTH)
  44. #define TH_FLD_WOCLR(fld) TH_MACRO_EXP(fld, _WOCLR)
  45. #define TH_FLD_WOSET(fld) TH_MACRO_EXP(fld, _WOSET)
  46. #define str(s) #s
  47. #define xstr(s) str(s)
  48. #define CTL_SHIFT 11
  49. #define PHY_SHIFT 11
  50. #define PI_SHIFT 10
  51. #define TH_OFFSET_FROM_REG(REG, SHIFT, offset) do {\
  52. char *i, *pstr= xstr(REG); offset = 0;\
  53. for (i = &pstr[SHIFT]; *i != '\0'; ++i) {\
  54. offset = offset * 10 + (*i - '0'); }\
  55. } while (0)
  56. static void j721e_lpddr4_ack_freq_upd_req(void)
  57. {
  58. unsigned int req_type, counter;
  59. debug("--->>> LPDDR4 Initialization is in progress ... <<<---\n");
  60. for (counter = 0; counter < ddrss->ddr_fhs_cnt; counter++) {
  61. if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
  62. CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
  63. true, 10000, false)) {
  64. printf("Timeout during frequency handshake\n");
  65. hang();
  66. }
  67. req_type = readl(ddrss->ddrss_ctrl_mmr +
  68. CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS) & 0x03;
  69. debug("%s: received freq change req: req type = %d, req no. = %d \n",
  70. __func__, req_type, counter);
  71. if (req_type == 1)
  72. clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
  73. else if (req_type == 2)
  74. clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq2);
  75. else if (req_type == 0)
  76. /* Put DDR pll in bypass mode */
  77. clk_set_rate(&ddrss->ddr_clk,
  78. clk_get_rate(&ddrss->osc_clk));
  79. else
  80. printf("%s: Invalid freq request type\n", __func__);
  81. writel(0x1, ddrss->ddrss_ctrl_mmr +
  82. CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
  83. if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
  84. CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
  85. false, 10, false)) {
  86. printf("Timeout during frequency handshake\n");
  87. hang();
  88. }
  89. writel(0x0, ddrss->ddrss_ctrl_mmr +
  90. CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
  91. }
  92. }
  93. static void j721e_lpddr4_info_handler(const lpddr4_privatedata * pd,
  94. lpddr4_infotype infotype)
  95. {
  96. if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE) {
  97. j721e_lpddr4_ack_freq_upd_req();
  98. }
  99. }
  100. static int j721e_ddrss_power_on(struct j721e_ddrss_desc *ddrss)
  101. {
  102. int ret;
  103. debug("%s(ddrss=%p)\n", __func__, ddrss);
  104. ret = power_domain_on(&ddrss->ddrcfg_pwrdmn);
  105. if (ret) {
  106. dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
  107. return ret;
  108. }
  109. ret = power_domain_on(&ddrss->ddrdata_pwrdmn);
  110. if (ret) {
  111. dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
  112. return ret;
  113. }
  114. return 0;
  115. }
  116. static int j721e_ddrss_ofdata_to_priv(struct udevice *dev)
  117. {
  118. struct j721e_ddrss_desc *ddrss = dev_get_priv(dev);
  119. phys_addr_t reg;
  120. int ret;
  121. debug("%s(dev=%p)\n", __func__, dev);
  122. reg = dev_read_addr_name(dev, "cfg");
  123. if (reg == FDT_ADDR_T_NONE) {
  124. dev_err(dev, "No reg property for DDRSS wrapper logic\n");
  125. return -EINVAL;
  126. }
  127. ddrss->ddrss_ss_cfg = (void *)reg;
  128. reg = dev_read_addr_name(dev, "ctrl_mmr_lp4");
  129. if (reg == FDT_ADDR_T_NONE) {
  130. dev_err(dev, "No reg property for CTRL MMR\n");
  131. return -EINVAL;
  132. }
  133. ddrss->ddrss_ctrl_mmr = (void *)reg;
  134. ret = power_domain_get_by_index(dev, &ddrss->ddrcfg_pwrdmn, 0);
  135. if (ret) {
  136. dev_err(dev, "power_domain_get() failed: %d\n", ret);
  137. return ret;
  138. }
  139. ret = power_domain_get_by_index(dev, &ddrss->ddrdata_pwrdmn, 1);
  140. if (ret) {
  141. dev_err(dev, "power_domain_get() failed: %d\n", ret);
  142. return ret;
  143. }
  144. ret = clk_get_by_index(dev, 0, &ddrss->ddr_clk);
  145. if (ret)
  146. dev_err(dev, "clk get failed%d\n", ret);
  147. ret = clk_get_by_index(dev, 1, &ddrss->osc_clk);
  148. if (ret)
  149. dev_err(dev, "clk get failed for osc clk %d\n", ret);
  150. ret = dev_read_u32(dev, "ti,ddr-freq1", &ddrss->ddr_freq1);
  151. if (ret)
  152. dev_err(dev, "ddr freq1 not populated %d\n", ret);
  153. ret = dev_read_u32(dev, "ti,ddr-freq2", &ddrss->ddr_freq2);
  154. if (ret)
  155. dev_err(dev, "ddr freq2 not populated %d\n", ret);
  156. ret = dev_read_u32(dev, "ti,ddr-fhs-cnt", &ddrss->ddr_fhs_cnt);
  157. if (ret)
  158. dev_err(dev, "ddr fhs cnt not populated %d\n", ret);
  159. /* Put DDR pll in bypass mode */
  160. ret = clk_set_rate(&ddrss->ddr_clk, clk_get_rate(&ddrss->osc_clk));
  161. if (ret)
  162. dev_err(dev, "ddr clk bypass failed\n");
  163. return ret;
  164. }
  165. void j721e_lpddr4_probe(void)
  166. {
  167. uint32_t status = 0U;
  168. uint16_t configsize = 0U;
  169. status = driverdt->probe(&config, &configsize);
  170. if ((status != 0) || (configsize != sizeof(lpddr4_privatedata))
  171. || (configsize > SRAM_MAX)) {
  172. printf("LPDDR4_Probe: FAIL\n");
  173. hang();
  174. } else {
  175. debug("LPDDR4_Probe: PASS\n");
  176. }
  177. }
  178. void j721e_lpddr4_init(void)
  179. {
  180. uint32_t status = 0U;
  181. if ((sizeof(pd) != sizeof(lpddr4_privatedata))
  182. || (sizeof(pd) > SRAM_MAX)) {
  183. printf("LPDDR4_Init: FAIL\n");
  184. hang();
  185. }
  186. config.ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
  187. config.infohandler = (lpddr4_infocallback) j721e_lpddr4_info_handler;
  188. status = driverdt->init(&pd, &config);
  189. if ((status > 0U) ||
  190. (pd.ctlbase != (struct lpddr4_ctlregs_s *)config.ctlbase) ||
  191. (pd.ctlinterrupthandler != config.ctlinterrupthandler) ||
  192. (pd.phyindepinterrupthandler != config.phyindepinterrupthandler)) {
  193. printf("LPDDR4_Init: FAIL\n");
  194. hang();
  195. } else {
  196. debug("LPDDR4_Init: PASS\n");
  197. }
  198. }
  199. void populate_data_array_from_dt(lpddr4_reginitdata * reginit_data)
  200. {
  201. int ret, i;
  202. ret = dev_read_u32_array(ddrss->dev, "ti,ctl-data",
  203. (u32 *) reginit_data->denalictlreg,
  204. LPDDR4_CTL_REG_COUNT);
  205. if (ret)
  206. printf("Error reading ctrl data\n");
  207. for (i = 0; i < LPDDR4_CTL_REG_COUNT; i++)
  208. reginit_data->updatectlreg[i] = true;
  209. ret = dev_read_u32_array(ddrss->dev, "ti,pi-data",
  210. (u32 *) reginit_data->denaliphyindepreg,
  211. LPDDR4_PHY_INDEP_REG_COUNT);
  212. if (ret)
  213. printf("Error reading PI data\n");
  214. for (i = 0; i < LPDDR4_PHY_INDEP_REG_COUNT; i++)
  215. reginit_data->updatephyindepreg[i] = true;
  216. ret = dev_read_u32_array(ddrss->dev, "ti,phy-data",
  217. (u32 *) reginit_data->denaliphyreg,
  218. LPDDR4_PHY_REG_COUNT);
  219. if (ret)
  220. printf("Error reading PHY data\n");
  221. for (i = 0; i < LPDDR4_PHY_REG_COUNT; i++)
  222. reginit_data->updatephyreg[i] = true;
  223. }
  224. void j721e_lpddr4_hardware_reg_init(void)
  225. {
  226. uint32_t status = 0U;
  227. lpddr4_reginitdata reginitdata;
  228. populate_data_array_from_dt(&reginitdata);
  229. status = driverdt->writectlconfig(&pd, &reginitdata);
  230. if (!status) {
  231. status = driverdt->writephyindepconfig(&pd, &reginitdata);
  232. }
  233. if (!status) {
  234. status = driverdt->writephyconfig(&pd, &reginitdata);
  235. }
  236. if (status) {
  237. printf(" ERROR: LPDDR4_HardwareRegInit failed!!\n");
  238. hang();
  239. }
  240. return;
  241. }
  242. void j721e_lpddr4_start(void)
  243. {
  244. uint32_t status = 0U;
  245. uint32_t regval = 0U;
  246. uint32_t offset = 0U;
  247. TH_OFFSET_FROM_REG(LPDDR4__START__REG, CTL_SHIFT, offset);
  248. status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
  249. if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 0U)) {
  250. printf("LPDDR4_StartTest: FAIL\n");
  251. hang();
  252. }
  253. status = driverdt->start(&pd);
  254. if (status > 0U) {
  255. printf("LPDDR4_StartTest: FAIL\n");
  256. hang();
  257. }
  258. status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
  259. if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 1U)) {
  260. printf("LPDDR4_Start: FAIL\n");
  261. hang();
  262. } else {
  263. debug("LPDDR4_Start: PASS\n");
  264. }
  265. }
  266. static int j721e_ddrss_probe(struct udevice *dev)
  267. {
  268. int ret;
  269. ddrss = dev_get_priv(dev);
  270. debug("%s(dev=%p)\n", __func__, dev);
  271. ret = j721e_ddrss_ofdata_to_priv(dev);
  272. if (ret)
  273. return ret;
  274. ddrss->dev = dev;
  275. ret = j721e_ddrss_power_on(ddrss);
  276. if (ret)
  277. return ret;
  278. driverdt = lpddr4_getinstance();
  279. j721e_lpddr4_probe();
  280. j721e_lpddr4_init();
  281. j721e_lpddr4_hardware_reg_init();
  282. j721e_lpddr4_start();
  283. return ret;
  284. }
  285. static int j721e_ddrss_get_info(struct udevice *dev, struct ram_info *info)
  286. {
  287. return 0;
  288. }
  289. static struct ram_ops j721e_ddrss_ops = {
  290. .get_info = j721e_ddrss_get_info,
  291. };
  292. static const struct udevice_id j721e_ddrss_ids[] = {
  293. {.compatible = "ti,j721e-ddrss"},
  294. {}
  295. };
  296. U_BOOT_DRIVER(j721e_ddrss) = {
  297. .name = "j721e_ddrss",
  298. .id = UCLASS_RAM,
  299. .of_match = j721e_ddrss_ids,
  300. .ops = &j721e_ddrss_ops,
  301. .probe = j721e_ddrss_probe,
  302. .priv_auto_alloc_size = sizeof(struct j721e_ddrss_desc),
  303. };