ti_k3_r5f_rproc.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Texas Instruments' K3 R5 Remoteproc driver
  4. *
  5. * Copyright (C) 2018-2020 Texas Instruments Incorporated - https://www.ti.com/
  6. * Lokesh Vutla <lokeshvutla@ti.com>
  7. * Suman Anna <s-anna@ti.com>
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <log.h>
  12. #include <malloc.h>
  13. #include <remoteproc.h>
  14. #include <errno.h>
  15. #include <clk.h>
  16. #include <reset.h>
  17. #include <asm/io.h>
  18. #include <dm/device_compat.h>
  19. #include <linux/err.h>
  20. #include <linux/kernel.h>
  21. #include <linux/soc/ti/ti_sci_protocol.h>
  22. #include "ti_sci_proc.h"
  23. /*
  24. * R5F's view of this address can either be for ATCM or BTCM with the other
  25. * at address 0x0 based on loczrama signal.
  26. */
  27. #define K3_R5_TCM_DEV_ADDR 0x41010000
  28. /* R5 TI-SCI Processor Configuration Flags */
  29. #define PROC_BOOT_CFG_FLAG_R5_DBG_EN 0x00000001
  30. #define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN 0x00000002
  31. #define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100
  32. #define PROC_BOOT_CFG_FLAG_R5_TEINIT 0x00000200
  33. #define PROC_BOOT_CFG_FLAG_R5_NMFI_EN 0x00000400
  34. #define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800
  35. #define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000
  36. #define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000
  37. #define PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR 0x10000000
  38. /* Available from J7200 SoCs onwards */
  39. #define PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS 0x00004000
  40. /* R5 TI-SCI Processor Control Flags */
  41. #define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
  42. /* R5 TI-SCI Processor Status Flags */
  43. #define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001
  44. #define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002
  45. #define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED 0x00000004
  46. #define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED 0x00000100
  47. #define NR_CORES 2
  48. enum cluster_mode {
  49. CLUSTER_MODE_SPLIT = 0,
  50. CLUSTER_MODE_LOCKSTEP,
  51. };
  52. /**
  53. * struct k3_r5f_ip_data - internal data structure used for IP variations
  54. * @tcm_is_double: flag to denote the larger unified TCMs in certain modes
  55. * @tcm_ecc_autoinit: flag to denote the auto-initialization of TCMs for ECC
  56. */
  57. struct k3_r5f_ip_data {
  58. bool tcm_is_double;
  59. bool tcm_ecc_autoinit;
  60. };
  61. /**
  62. * struct k3_r5_mem - internal memory structure
  63. * @cpu_addr: MPU virtual address of the memory region
  64. * @bus_addr: Bus address used to access the memory region
  65. * @dev_addr: Device address from remoteproc view
  66. * @size: Size of the memory region
  67. */
  68. struct k3_r5f_mem {
  69. void __iomem *cpu_addr;
  70. phys_addr_t bus_addr;
  71. u32 dev_addr;
  72. size_t size;
  73. };
  74. /**
  75. * struct k3_r5f_core - K3 R5 core structure
  76. * @dev: cached device pointer
  77. * @cluster: pointer to the parent cluster.
  78. * @reset: reset control handle
  79. * @tsp: TI-SCI processor control handle
  80. * @ipdata: cached pointer to R5F IP specific feature data
  81. * @mem: Array of available internal memories
  82. * @num_mem: Number of available memories
  83. * @atcm_enable: flag to control ATCM enablement
  84. * @btcm_enable: flag to control BTCM enablement
  85. * @loczrama: flag to dictate which TCM is at device address 0x0
  86. * @in_use: flag to tell if the core is already in use.
  87. */
  88. struct k3_r5f_core {
  89. struct udevice *dev;
  90. struct k3_r5f_cluster *cluster;
  91. struct reset_ctl reset;
  92. struct ti_sci_proc tsp;
  93. struct k3_r5f_ip_data *ipdata;
  94. struct k3_r5f_mem *mem;
  95. int num_mems;
  96. u32 atcm_enable;
  97. u32 btcm_enable;
  98. u32 loczrama;
  99. bool in_use;
  100. };
  101. /**
  102. * struct k3_r5f_cluster - K3 R5F Cluster structure
  103. * @mode: Mode to configure the Cluster - Split or LockStep
  104. * @cores: Array of pointers to R5 cores within the cluster
  105. */
  106. struct k3_r5f_cluster {
  107. enum cluster_mode mode;
  108. struct k3_r5f_core *cores[NR_CORES];
  109. };
  110. static bool is_primary_core(struct k3_r5f_core *core)
  111. {
  112. return core == core->cluster->cores[0];
  113. }
  114. static int k3_r5f_proc_request(struct k3_r5f_core *core)
  115. {
  116. struct k3_r5f_cluster *cluster = core->cluster;
  117. int i, ret;
  118. if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
  119. for (i = 0; i < NR_CORES; i++) {
  120. ret = ti_sci_proc_request(&cluster->cores[i]->tsp);
  121. if (ret)
  122. goto proc_release;
  123. }
  124. } else {
  125. ret = ti_sci_proc_request(&core->tsp);
  126. }
  127. return 0;
  128. proc_release:
  129. while (i >= 0) {
  130. ti_sci_proc_release(&cluster->cores[i]->tsp);
  131. i--;
  132. }
  133. return ret;
  134. }
  135. static void k3_r5f_proc_release(struct k3_r5f_core *core)
  136. {
  137. struct k3_r5f_cluster *cluster = core->cluster;
  138. int i;
  139. if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
  140. for (i = 0; i < NR_CORES; i++)
  141. ti_sci_proc_release(&cluster->cores[i]->tsp);
  142. else
  143. ti_sci_proc_release(&core->tsp);
  144. }
  145. static int k3_r5f_lockstep_release(struct k3_r5f_cluster *cluster)
  146. {
  147. int ret, c;
  148. debug("%s\n", __func__);
  149. for (c = NR_CORES - 1; c >= 0; c--) {
  150. ret = ti_sci_proc_power_domain_on(&cluster->cores[c]->tsp);
  151. if (ret)
  152. goto unroll_module_reset;
  153. }
  154. /* deassert local reset on all applicable cores */
  155. for (c = NR_CORES - 1; c >= 0; c--) {
  156. ret = reset_deassert(&cluster->cores[c]->reset);
  157. if (ret)
  158. goto unroll_local_reset;
  159. }
  160. return 0;
  161. unroll_local_reset:
  162. while (c < NR_CORES) {
  163. reset_assert(&cluster->cores[c]->reset);
  164. c++;
  165. }
  166. c = 0;
  167. unroll_module_reset:
  168. while (c < NR_CORES) {
  169. ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp);
  170. c++;
  171. }
  172. return ret;
  173. }
  174. static int k3_r5f_split_release(struct k3_r5f_core *core)
  175. {
  176. int ret;
  177. dev_dbg(core->dev, "%s\n", __func__);
  178. ret = ti_sci_proc_power_domain_on(&core->tsp);
  179. if (ret) {
  180. dev_err(core->dev, "module-reset deassert failed, ret = %d\n",
  181. ret);
  182. return ret;
  183. }
  184. ret = reset_deassert(&core->reset);
  185. if (ret) {
  186. dev_err(core->dev, "local-reset deassert failed, ret = %d\n",
  187. ret);
  188. if (ti_sci_proc_power_domain_off(&core->tsp))
  189. dev_warn(core->dev, "module-reset assert back failed\n");
  190. }
  191. return ret;
  192. }
  193. static int k3_r5f_prepare(struct udevice *dev)
  194. {
  195. struct k3_r5f_core *core = dev_get_priv(dev);
  196. struct k3_r5f_cluster *cluster = core->cluster;
  197. int ret = 0;
  198. dev_dbg(dev, "%s\n", __func__);
  199. if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
  200. ret = k3_r5f_lockstep_release(cluster);
  201. else
  202. ret = k3_r5f_split_release(core);
  203. if (ret)
  204. dev_err(dev, "Unable to enable cores for TCM loading %d\n",
  205. ret);
  206. return ret;
  207. }
  208. static int k3_r5f_core_sanity_check(struct k3_r5f_core *core)
  209. {
  210. struct k3_r5f_cluster *cluster = core->cluster;
  211. if (core->in_use) {
  212. dev_err(core->dev,
  213. "Invalid op: Trying to load/start on already running core %d\n",
  214. core->tsp.proc_id);
  215. return -EINVAL;
  216. }
  217. if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !cluster->cores[1]) {
  218. dev_err(core->dev,
  219. "Secondary core is not probed in this cluster\n");
  220. return -EAGAIN;
  221. }
  222. if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !is_primary_core(core)) {
  223. dev_err(core->dev,
  224. "Invalid op: Trying to start secondary core %d in lockstep mode\n",
  225. core->tsp.proc_id);
  226. return -EINVAL;
  227. }
  228. if (cluster->mode == CLUSTER_MODE_SPLIT && !is_primary_core(core)) {
  229. if (!core->cluster->cores[0]->in_use) {
  230. dev_err(core->dev,
  231. "Invalid seq: Enable primary core before loading secondary core\n");
  232. return -EINVAL;
  233. }
  234. }
  235. return 0;
  236. }
  237. /* Zero out TCMs so that ECC can be effective on all TCM addresses */
  238. void k3_r5f_init_tcm_memories(struct k3_r5f_core *core, bool auto_inited)
  239. {
  240. if (core->ipdata->tcm_ecc_autoinit && auto_inited)
  241. return;
  242. if (core->atcm_enable)
  243. memset(core->mem[0].cpu_addr, 0x00, core->mem[0].size);
  244. if (core->btcm_enable)
  245. memset(core->mem[1].cpu_addr, 0x00, core->mem[1].size);
  246. }
  247. /**
  248. * k3_r5f_load() - Load up the Remote processor image
  249. * @dev: rproc device pointer
  250. * @addr: Address at which image is available
  251. * @size: size of the image
  252. *
  253. * Return: 0 if all goes good, else appropriate error message.
  254. */
  255. static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
  256. {
  257. struct k3_r5f_core *core = dev_get_priv(dev);
  258. u64 boot_vector;
  259. u32 ctrl, sts, cfg = 0;
  260. bool mem_auto_init;
  261. int ret;
  262. dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
  263. ret = k3_r5f_core_sanity_check(core);
  264. if (ret)
  265. return ret;
  266. ret = k3_r5f_proc_request(core);
  267. if (ret)
  268. return ret;
  269. ret = ti_sci_proc_get_status(&core->tsp, &boot_vector, &cfg, &ctrl,
  270. &sts);
  271. if (ret)
  272. return ret;
  273. mem_auto_init = !(cfg & PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS);
  274. ret = k3_r5f_prepare(dev);
  275. if (ret) {
  276. dev_err(dev, "R5f prepare failed for core %d\n",
  277. core->tsp.proc_id);
  278. goto proc_release;
  279. }
  280. k3_r5f_init_tcm_memories(core, mem_auto_init);
  281. ret = rproc_elf_load_image(dev, addr, size);
  282. if (ret < 0) {
  283. dev_err(dev, "Loading elf failedi %d\n", ret);
  284. goto proc_release;
  285. }
  286. boot_vector = rproc_elf_get_boot_addr(dev, addr);
  287. dev_dbg(dev, "%s: Boot vector = 0x%llx\n", __func__, boot_vector);
  288. ret = ti_sci_proc_set_config(&core->tsp, boot_vector, 0, 0);
  289. proc_release:
  290. k3_r5f_proc_release(core);
  291. return ret;
  292. }
  293. static int k3_r5f_core_halt(struct k3_r5f_core *core)
  294. {
  295. int ret;
  296. ret = ti_sci_proc_set_control(&core->tsp,
  297. PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0);
  298. if (ret)
  299. dev_err(core->dev, "Core %d failed to stop\n",
  300. core->tsp.proc_id);
  301. return ret;
  302. }
  303. static int k3_r5f_core_run(struct k3_r5f_core *core)
  304. {
  305. int ret;
  306. ret = ti_sci_proc_set_control(&core->tsp,
  307. 0, PROC_BOOT_CTRL_FLAG_R5_CORE_HALT);
  308. if (ret) {
  309. dev_err(core->dev, "Core %d failed to start\n",
  310. core->tsp.proc_id);
  311. return ret;
  312. }
  313. return 0;
  314. }
  315. /**
  316. * k3_r5f_start() - Start the remote processor
  317. * @dev: rproc device pointer
  318. *
  319. * Return: 0 if all went ok, else return appropriate error
  320. */
  321. static int k3_r5f_start(struct udevice *dev)
  322. {
  323. struct k3_r5f_core *core = dev_get_priv(dev);
  324. struct k3_r5f_cluster *cluster = core->cluster;
  325. int ret, c;
  326. dev_dbg(dev, "%s\n", __func__);
  327. ret = k3_r5f_core_sanity_check(core);
  328. if (ret)
  329. return ret;
  330. ret = k3_r5f_proc_request(core);
  331. if (ret)
  332. return ret;
  333. if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
  334. if (is_primary_core(core)) {
  335. for (c = NR_CORES - 1; c >= 0; c--) {
  336. ret = k3_r5f_core_run(cluster->cores[c]);
  337. if (ret)
  338. goto unroll_core_run;
  339. }
  340. } else {
  341. dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
  342. core->tsp.proc_id);
  343. ret = -EINVAL;
  344. goto proc_release;
  345. }
  346. } else {
  347. ret = k3_r5f_core_run(core);
  348. if (ret)
  349. goto proc_release;
  350. }
  351. core->in_use = true;
  352. k3_r5f_proc_release(core);
  353. return 0;
  354. unroll_core_run:
  355. while (c < NR_CORES) {
  356. k3_r5f_core_halt(cluster->cores[c]);
  357. c++;
  358. }
  359. proc_release:
  360. k3_r5f_proc_release(core);
  361. return ret;
  362. }
  363. static int k3_r5f_split_reset(struct k3_r5f_core *core)
  364. {
  365. int ret;
  366. dev_dbg(core->dev, "%s\n", __func__);
  367. if (reset_assert(&core->reset))
  368. ret = -EINVAL;
  369. if (ti_sci_proc_power_domain_off(&core->tsp))
  370. ret = -EINVAL;
  371. return ret;
  372. }
  373. static int k3_r5f_lockstep_reset(struct k3_r5f_cluster *cluster)
  374. {
  375. int ret = 0, c;
  376. debug("%s\n", __func__);
  377. for (c = 0; c < NR_CORES; c++)
  378. if (reset_assert(&cluster->cores[c]->reset))
  379. ret = -EINVAL;
  380. /* disable PSC modules on all applicable cores */
  381. for (c = 0; c < NR_CORES; c++)
  382. if (ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp))
  383. ret = -EINVAL;
  384. return ret;
  385. }
  386. static int k3_r5f_unprepare(struct udevice *dev)
  387. {
  388. struct k3_r5f_core *core = dev_get_priv(dev);
  389. struct k3_r5f_cluster *cluster = core->cluster;
  390. int ret;
  391. dev_dbg(dev, "%s\n", __func__);
  392. if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
  393. if (is_primary_core(core))
  394. ret = k3_r5f_lockstep_reset(cluster);
  395. } else {
  396. ret = k3_r5f_split_reset(core);
  397. }
  398. if (ret)
  399. dev_warn(dev, "Unable to enable cores for TCM loading %d\n",
  400. ret);
  401. return 0;
  402. }
  403. static int k3_r5f_stop(struct udevice *dev)
  404. {
  405. struct k3_r5f_core *core = dev_get_priv(dev);
  406. struct k3_r5f_cluster *cluster = core->cluster;
  407. int c, ret;
  408. dev_dbg(dev, "%s\n", __func__);
  409. ret = k3_r5f_proc_request(core);
  410. if (ret)
  411. return ret;
  412. core->in_use = false;
  413. if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
  414. if (is_primary_core(core)) {
  415. for (c = 0; c < NR_CORES; c++)
  416. k3_r5f_core_halt(cluster->cores[c]);
  417. } else {
  418. dev_err(dev, "Invalid op: Trying to stop secondary core in lockstep mode\n");
  419. ret = -EINVAL;
  420. goto proc_release;
  421. }
  422. } else {
  423. k3_r5f_core_halt(core);
  424. }
  425. ret = k3_r5f_unprepare(dev);
  426. proc_release:
  427. k3_r5f_proc_release(core);
  428. return ret;
  429. }
  430. static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size)
  431. {
  432. struct k3_r5f_core *core = dev_get_priv(dev);
  433. void __iomem *va = NULL;
  434. phys_addr_t bus_addr;
  435. u32 dev_addr, offset;
  436. ulong mem_size;
  437. int i;
  438. dev_dbg(dev, "%s\n", __func__);
  439. if (size <= 0)
  440. return NULL;
  441. for (i = 0; i < core->num_mems; i++) {
  442. bus_addr = core->mem[i].bus_addr;
  443. dev_addr = core->mem[i].dev_addr;
  444. mem_size = core->mem[i].size;
  445. if (da >= bus_addr && (da + size) <= (bus_addr + mem_size)) {
  446. offset = da - bus_addr;
  447. va = core->mem[i].cpu_addr + offset;
  448. return (__force void *)va;
  449. }
  450. if (da >= dev_addr && (da + size) <= (dev_addr + mem_size)) {
  451. offset = da - dev_addr;
  452. va = core->mem[i].cpu_addr + offset;
  453. return (__force void *)va;
  454. }
  455. }
  456. /* Assume it is DDR region and return da */
  457. return map_physmem(da, size, MAP_NOCACHE);
  458. }
  459. static int k3_r5f_init(struct udevice *dev)
  460. {
  461. return 0;
  462. }
  463. static int k3_r5f_reset(struct udevice *dev)
  464. {
  465. return 0;
  466. }
  467. static const struct dm_rproc_ops k3_r5f_rproc_ops = {
  468. .init = k3_r5f_init,
  469. .reset = k3_r5f_reset,
  470. .start = k3_r5f_start,
  471. .stop = k3_r5f_stop,
  472. .load = k3_r5f_load,
  473. .device_to_virt = k3_r5f_da_to_va,
  474. };
  475. static int k3_r5f_rproc_configure(struct k3_r5f_core *core)
  476. {
  477. struct k3_r5f_cluster *cluster = core->cluster;
  478. u32 set_cfg = 0, clr_cfg = 0, cfg, ctrl, sts;
  479. bool lockstep_permitted;
  480. u64 boot_vec = 0;
  481. int ret;
  482. dev_dbg(core->dev, "%s\n", __func__);
  483. ret = ti_sci_proc_request(&core->tsp);
  484. if (ret < 0)
  485. return ret;
  486. /* Do not touch boot vector now. Load will take care of it. */
  487. clr_cfg |= PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR;
  488. ret = ti_sci_proc_get_status(&core->tsp, &boot_vec, &cfg, &ctrl, &sts);
  489. if (ret)
  490. goto out;
  491. /* Sanity check for Lockstep mode */
  492. lockstep_permitted = !!(sts &
  493. PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED);
  494. if (cluster->mode && is_primary_core(core) && !lockstep_permitted) {
  495. dev_err(core->dev, "LockStep mode not permitted on this device\n");
  496. ret = -EINVAL;
  497. goto out;
  498. }
  499. /* Primary core only configuration */
  500. if (is_primary_core(core)) {
  501. /* always enable ARM mode */
  502. clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TEINIT;
  503. if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
  504. set_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
  505. else if (lockstep_permitted)
  506. clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
  507. }
  508. if (core->atcm_enable)
  509. set_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
  510. else
  511. clr_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
  512. if (core->btcm_enable)
  513. set_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
  514. else
  515. clr_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
  516. if (core->loczrama)
  517. set_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
  518. else
  519. clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
  520. ret = k3_r5f_core_halt(core);
  521. if (ret)
  522. goto out;
  523. ret = ti_sci_proc_set_config(&core->tsp, boot_vec, set_cfg, clr_cfg);
  524. out:
  525. ti_sci_proc_release(&core->tsp);
  526. return ret;
  527. }
  528. static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
  529. {
  530. u32 ids[2];
  531. int ret;
  532. dev_dbg(dev, "%s\n", __func__);
  533. tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
  534. if (IS_ERR(tsp->sci)) {
  535. dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
  536. return PTR_ERR(tsp->sci);
  537. }
  538. ret = dev_read_u32_array(dev, "ti,sci-proc-ids", ids, 2);
  539. if (ret) {
  540. dev_err(dev, "Proc IDs not populated %d\n", ret);
  541. return ret;
  542. }
  543. tsp->ops = &tsp->sci->ops.proc_ops;
  544. tsp->proc_id = ids[0];
  545. tsp->host_id = ids[1];
  546. tsp->dev_id = dev_read_u32_default(dev, "ti,sci-dev-id",
  547. TI_SCI_RESOURCE_NULL);
  548. if (tsp->dev_id == TI_SCI_RESOURCE_NULL) {
  549. dev_err(dev, "Device ID not populated %d\n", ret);
  550. return -ENODEV;
  551. }
  552. return 0;
  553. }
  554. static int k3_r5f_of_to_priv(struct k3_r5f_core *core)
  555. {
  556. int ret;
  557. dev_dbg(core->dev, "%s\n", __func__);
  558. core->atcm_enable = dev_read_u32_default(core->dev, "atcm-enable", 0);
  559. core->btcm_enable = dev_read_u32_default(core->dev, "btcm-enable", 1);
  560. core->loczrama = dev_read_u32_default(core->dev, "loczrama", 1);
  561. ret = ti_sci_proc_of_to_priv(core->dev, &core->tsp);
  562. if (ret)
  563. return ret;
  564. ret = reset_get_by_index(core->dev, 0, &core->reset);
  565. if (ret) {
  566. dev_err(core->dev, "Reset lines not available: %d\n", ret);
  567. return ret;
  568. }
  569. core->ipdata = (struct k3_r5f_ip_data *)dev_get_driver_data(core->dev);
  570. return 0;
  571. }
  572. static int k3_r5f_core_of_get_memories(struct k3_r5f_core *core)
  573. {
  574. static const char * const mem_names[] = {"atcm", "btcm"};
  575. struct udevice *dev = core->dev;
  576. int i;
  577. dev_dbg(dev, "%s\n", __func__);
  578. core->num_mems = ARRAY_SIZE(mem_names);
  579. core->mem = calloc(core->num_mems, sizeof(*core->mem));
  580. if (!core->mem)
  581. return -ENOMEM;
  582. for (i = 0; i < core->num_mems; i++) {
  583. core->mem[i].bus_addr = dev_read_addr_size_name(dev,
  584. mem_names[i],
  585. (fdt_addr_t *)&core->mem[i].size);
  586. if (core->mem[i].bus_addr == FDT_ADDR_T_NONE) {
  587. dev_err(dev, "%s bus address not found\n",
  588. mem_names[i]);
  589. return -EINVAL;
  590. }
  591. core->mem[i].cpu_addr = map_physmem(core->mem[i].bus_addr,
  592. core->mem[i].size,
  593. MAP_NOCACHE);
  594. if (!strcmp(mem_names[i], "atcm")) {
  595. core->mem[i].dev_addr = core->loczrama ?
  596. 0 : K3_R5_TCM_DEV_ADDR;
  597. } else {
  598. core->mem[i].dev_addr = core->loczrama ?
  599. K3_R5_TCM_DEV_ADDR : 0;
  600. }
  601. dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
  602. mem_names[i], &core->mem[i].bus_addr,
  603. core->mem[i].size, core->mem[i].cpu_addr,
  604. core->mem[i].dev_addr);
  605. }
  606. return 0;
  607. }
  608. /*
  609. * Each R5F core within a typical R5FSS instance has a total of 64 KB of TCMs,
  610. * split equally into two 32 KB banks between ATCM and BTCM. The TCMs from both
  611. * cores are usable in Split-mode, but only the Core0 TCMs can be used in
  612. * LockStep-mode. The newer revisions of the R5FSS IP maximizes these TCMs by
  613. * leveraging the Core1 TCMs as well in certain modes where they would have
  614. * otherwise been unusable (Eg: LockStep-mode on J7200 SoCs). This is done by
  615. * making a Core1 TCM visible immediately after the corresponding Core0 TCM.
  616. * The SoC memory map uses the larger 64 KB sizes for the Core0 TCMs, and the
  617. * dts representation reflects this increased size on supported SoCs. The Core0
  618. * TCM sizes therefore have to be adjusted to only half the original size in
  619. * Split mode.
  620. */
  621. static void k3_r5f_core_adjust_tcm_sizes(struct k3_r5f_core *core)
  622. {
  623. struct k3_r5f_cluster *cluster = core->cluster;
  624. if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
  625. return;
  626. if (!core->ipdata->tcm_is_double)
  627. return;
  628. if (core == cluster->cores[0]) {
  629. core->mem[0].size /= 2;
  630. core->mem[1].size /= 2;
  631. dev_dbg(core->dev, "adjusted TCM sizes, ATCM = 0x%zx BTCM = 0x%zx\n",
  632. core->mem[0].size, core->mem[1].size);
  633. }
  634. }
  635. /**
  636. * k3_r5f_probe() - Basic probe
  637. * @dev: corresponding k3 remote processor device
  638. *
  639. * Return: 0 if all goes good, else appropriate error message.
  640. */
  641. static int k3_r5f_probe(struct udevice *dev)
  642. {
  643. struct k3_r5f_cluster *cluster = dev_get_priv(dev->parent);
  644. struct k3_r5f_core *core = dev_get_priv(dev);
  645. bool r_state;
  646. int ret;
  647. dev_dbg(dev, "%s\n", __func__);
  648. core->dev = dev;
  649. ret = k3_r5f_of_to_priv(core);
  650. if (ret)
  651. return ret;
  652. core->cluster = cluster;
  653. /* Assume Primary core gets probed first */
  654. if (!cluster->cores[0])
  655. cluster->cores[0] = core;
  656. else
  657. cluster->cores[1] = core;
  658. ret = k3_r5f_core_of_get_memories(core);
  659. if (ret) {
  660. dev_err(dev, "Rproc getting internal memories failed\n");
  661. return ret;
  662. }
  663. ret = core->tsp.sci->ops.dev_ops.is_on(core->tsp.sci, core->tsp.dev_id,
  664. &r_state, &core->in_use);
  665. if (ret)
  666. return ret;
  667. if (core->in_use) {
  668. dev_info(dev, "Core %d is already in use. No rproc commands work\n",
  669. core->tsp.proc_id);
  670. return 0;
  671. }
  672. /* Make sure Local reset is asserted. Redundant? */
  673. reset_assert(&core->reset);
  674. ret = k3_r5f_rproc_configure(core);
  675. if (ret) {
  676. dev_err(dev, "rproc configure failed %d\n", ret);
  677. return ret;
  678. }
  679. k3_r5f_core_adjust_tcm_sizes(core);
  680. dev_dbg(dev, "Remoteproc successfully probed\n");
  681. return 0;
  682. }
  683. static int k3_r5f_remove(struct udevice *dev)
  684. {
  685. struct k3_r5f_core *core = dev_get_priv(dev);
  686. free(core->mem);
  687. ti_sci_proc_release(&core->tsp);
  688. return 0;
  689. }
  690. static const struct k3_r5f_ip_data k3_data = {
  691. .tcm_is_double = false,
  692. .tcm_ecc_autoinit = false,
  693. };
  694. static const struct k3_r5f_ip_data j7200_data = {
  695. .tcm_is_double = true,
  696. .tcm_ecc_autoinit = true,
  697. };
  698. static const struct udevice_id k3_r5f_rproc_ids[] = {
  699. { .compatible = "ti,am654-r5f", .data = (ulong)&k3_data, },
  700. { .compatible = "ti,j721e-r5f", .data = (ulong)&k3_data, },
  701. { .compatible = "ti,j7200-r5f", .data = (ulong)&j7200_data, },
  702. {}
  703. };
  704. U_BOOT_DRIVER(k3_r5f_rproc) = {
  705. .name = "k3_r5f_rproc",
  706. .of_match = k3_r5f_rproc_ids,
  707. .id = UCLASS_REMOTEPROC,
  708. .ops = &k3_r5f_rproc_ops,
  709. .probe = k3_r5f_probe,
  710. .remove = k3_r5f_remove,
  711. .priv_auto_alloc_size = sizeof(struct k3_r5f_core),
  712. };
  713. static int k3_r5f_cluster_probe(struct udevice *dev)
  714. {
  715. struct k3_r5f_cluster *cluster = dev_get_priv(dev);
  716. dev_dbg(dev, "%s\n", __func__);
  717. cluster->mode = dev_read_u32_default(dev, "lockstep-mode",
  718. CLUSTER_MODE_LOCKSTEP);
  719. if (device_get_child_count(dev) != 2) {
  720. dev_err(dev, "Invalid number of R5 cores");
  721. return -EINVAL;
  722. }
  723. dev_dbg(dev, "%s: Cluster successfully probed in %s mode\n",
  724. __func__, cluster->mode ? "lockstep" : "split");
  725. return 0;
  726. }
  727. static const struct udevice_id k3_r5fss_ids[] = {
  728. { .compatible = "ti,am654-r5fss"},
  729. { .compatible = "ti,j721e-r5fss"},
  730. { .compatible = "ti,j7200-r5fss"},
  731. {}
  732. };
  733. U_BOOT_DRIVER(k3_r5fss) = {
  734. .name = "k3_r5fss",
  735. .of_match = k3_r5fss_ids,
  736. .id = UCLASS_MISC,
  737. .probe = k3_r5f_cluster_probe,
  738. .priv_auto_alloc_size = sizeof(struct k3_r5f_cluster),
  739. .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
  740. };