mtk_vpu.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. /*
  2. * Copyright (c) 2016 MediaTek Inc.
  3. * Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/debugfs.h>
  16. #include <linux/firmware.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/iommu.h>
  19. #include <linux/module.h>
  20. #include <linux/of_address.h>
  21. #include <linux/of_irq.h>
  22. #include <linux/of_platform.h>
  23. #include <linux/of_reserved_mem.h>
  24. #include <linux/sched.h>
  25. #include <linux/sizes.h>
  26. #include "mtk_vpu.h"
  27. /**
  28. * VPU (video processor unit) is a tiny processor controlling video hardware
  29. * related to video codec, scaling and color format converting.
  30. * VPU interfaces with other blocks by share memory and interrupt.
  31. **/
  32. #define INIT_TIMEOUT_MS 2000U
  33. #define IPI_TIMEOUT_MS 2000U
  34. #define VPU_FW_VER_LEN 16
  35. /* maximum program/data TCM (Tightly-Coupled Memory) size */
  36. #define VPU_PTCM_SIZE (96 * SZ_1K)
  37. #define VPU_DTCM_SIZE (32 * SZ_1K)
  38. /* the offset to get data tcm address */
  39. #define VPU_DTCM_OFFSET 0x18000UL
  40. /* daynamic allocated maximum extended memory size */
  41. #define VPU_EXT_P_SIZE SZ_1M
  42. #define VPU_EXT_D_SIZE SZ_4M
  43. /* maximum binary firmware size */
  44. #define VPU_P_FW_SIZE (VPU_PTCM_SIZE + VPU_EXT_P_SIZE)
  45. #define VPU_D_FW_SIZE (VPU_DTCM_SIZE + VPU_EXT_D_SIZE)
  46. /* the size of share buffer between Host and VPU */
  47. #define SHARE_BUF_SIZE 48
  48. /* binary firmware name */
  49. #define VPU_P_FW "vpu_p.bin"
  50. #define VPU_D_FW "vpu_d.bin"
  51. #define VPU_RESET 0x0
  52. #define VPU_TCM_CFG 0x0008
  53. #define VPU_PMEM_EXT0_ADDR 0x000C
  54. #define VPU_PMEM_EXT1_ADDR 0x0010
  55. #define VPU_TO_HOST 0x001C
  56. #define VPU_DMEM_EXT0_ADDR 0x0014
  57. #define VPU_DMEM_EXT1_ADDR 0x0018
  58. #define HOST_TO_VPU 0x0024
  59. #define VPU_PC_REG 0x0060
  60. #define VPU_WDT_REG 0x0084
  61. /* vpu inter-processor communication interrupt */
  62. #define VPU_IPC_INT BIT(8)
  63. /**
  64. * enum vpu_fw_type - VPU firmware type
  65. *
  66. * @P_FW: program firmware
  67. * @D_FW: data firmware
  68. *
  69. */
  70. enum vpu_fw_type {
  71. P_FW,
  72. D_FW,
  73. };
  74. /**
  75. * struct vpu_mem - VPU extended program/data memory information
  76. *
  77. * @va: the kernel virtual memory address of VPU extended memory
  78. * @pa: the physical memory address of VPU extended memory
  79. *
  80. */
  81. struct vpu_mem {
  82. void *va;
  83. dma_addr_t pa;
  84. };
  85. /**
  86. * struct vpu_regs - VPU TCM and configuration registers
  87. *
  88. * @tcm: the register for VPU Tightly-Coupled Memory
  89. * @cfg: the register for VPU configuration
  90. * @irq: the irq number for VPU interrupt
  91. */
  92. struct vpu_regs {
  93. void __iomem *tcm;
  94. void __iomem *cfg;
  95. int irq;
  96. };
  97. /**
  98. * struct vpu_wdt_handler - VPU watchdog reset handler
  99. *
  100. * @reset_func: reset handler
  101. * @priv: private data
  102. */
  103. struct vpu_wdt_handler {
  104. void (*reset_func)(void *);
  105. void *priv;
  106. };
  107. /**
  108. * struct vpu_wdt - VPU watchdog workqueue
  109. *
  110. * @handler: VPU watchdog reset handler
  111. * @ws: workstruct for VPU watchdog
  112. * @wq: workqueue for VPU watchdog
  113. */
  114. struct vpu_wdt {
  115. struct vpu_wdt_handler handler[VPU_RST_MAX];
  116. struct work_struct ws;
  117. struct workqueue_struct *wq;
  118. };
  119. /**
  120. * struct vpu_run - VPU initialization status
  121. *
  122. * @signaled: the signal of vpu initialization completed
  123. * @fw_ver: VPU firmware version
  124. * @dec_capability: decoder capability which is not used for now and
  125. * the value is reserved for future use
  126. * @enc_capability: encoder capability which is not used for now and
  127. * the value is reserved for future use
  128. * @wq: wait queue for VPU initialization status
  129. */
  130. struct vpu_run {
  131. u32 signaled;
  132. char fw_ver[VPU_FW_VER_LEN];
  133. unsigned int dec_capability;
  134. unsigned int enc_capability;
  135. wait_queue_head_t wq;
  136. };
  137. /**
  138. * struct vpu_ipi_desc - VPU IPI descriptor
  139. *
  140. * @handler: IPI handler
  141. * @name: the name of IPI handler
  142. * @priv: the private data of IPI handler
  143. */
  144. struct vpu_ipi_desc {
  145. ipi_handler_t handler;
  146. const char *name;
  147. void *priv;
  148. };
  149. /**
  150. * struct share_obj - DTCM (Data Tightly-Coupled Memory) buffer shared with
  151. * AP and VPU
  152. *
  153. * @id: IPI id
  154. * @len: share buffer length
  155. * @share_buf: share buffer data
  156. */
  157. struct share_obj {
  158. s32 id;
  159. u32 len;
  160. unsigned char share_buf[SHARE_BUF_SIZE];
  161. };
  162. /**
  163. * struct mtk_vpu - vpu driver data
  164. * @extmem: VPU extended memory information
  165. * @reg: VPU TCM and configuration registers
  166. * @run: VPU initialization status
  167. * @ipi_desc: VPU IPI descriptor
  168. * @recv_buf: VPU DTCM share buffer for receiving. The
  169. * receive buffer is only accessed in interrupt context.
  170. * @send_buf: VPU DTCM share buffer for sending
  171. * @dev: VPU struct device
  172. * @clk: VPU clock on/off
  173. * @fw_loaded: indicate VPU firmware loaded
  174. * @enable_4GB: VPU 4GB mode on/off
  175. * @vpu_mutex: protect mtk_vpu (except recv_buf) and ensure only
  176. * one client to use VPU service at a time. For example,
  177. * suppose a client is using VPU to decode VP8.
  178. * If the other client wants to encode VP8,
  179. * it has to wait until VP8 decode completes.
  180. * @wdt_refcnt WDT reference count to make sure the watchdog can be
  181. * disabled if no other client is using VPU service
  182. * @ack_wq: The wait queue for each codec and mdp. When sleeping
  183. * processes wake up, they will check the condition
  184. * "ipi_id_ack" to run the corresponding action or
  185. * go back to sleep.
  186. * @ipi_id_ack: The ACKs for registered IPI function sending
  187. * interrupt to VPU
  188. *
  189. */
  190. struct mtk_vpu {
  191. struct vpu_mem extmem[2];
  192. struct vpu_regs reg;
  193. struct vpu_run run;
  194. struct vpu_wdt wdt;
  195. struct vpu_ipi_desc ipi_desc[IPI_MAX];
  196. struct share_obj *recv_buf;
  197. struct share_obj *send_buf;
  198. struct device *dev;
  199. struct clk *clk;
  200. bool fw_loaded;
  201. bool enable_4GB;
  202. struct mutex vpu_mutex; /* for protecting vpu data data structure */
  203. u32 wdt_refcnt;
  204. wait_queue_head_t ack_wq;
  205. bool ipi_id_ack[IPI_MAX];
  206. };
  207. static inline void vpu_cfg_writel(struct mtk_vpu *vpu, u32 val, u32 offset)
  208. {
  209. writel(val, vpu->reg.cfg + offset);
  210. }
  211. static inline u32 vpu_cfg_readl(struct mtk_vpu *vpu, u32 offset)
  212. {
  213. return readl(vpu->reg.cfg + offset);
  214. }
  215. static inline bool vpu_running(struct mtk_vpu *vpu)
  216. {
  217. return vpu_cfg_readl(vpu, VPU_RESET) & BIT(0);
  218. }
  219. static void vpu_clock_disable(struct mtk_vpu *vpu)
  220. {
  221. /* Disable VPU watchdog */
  222. mutex_lock(&vpu->vpu_mutex);
  223. if (!--vpu->wdt_refcnt)
  224. vpu_cfg_writel(vpu,
  225. vpu_cfg_readl(vpu, VPU_WDT_REG) & ~(1L << 31),
  226. VPU_WDT_REG);
  227. mutex_unlock(&vpu->vpu_mutex);
  228. clk_disable(vpu->clk);
  229. }
  230. static int vpu_clock_enable(struct mtk_vpu *vpu)
  231. {
  232. int ret;
  233. ret = clk_enable(vpu->clk);
  234. if (ret)
  235. return ret;
  236. /* Enable VPU watchdog */
  237. mutex_lock(&vpu->vpu_mutex);
  238. if (!vpu->wdt_refcnt++)
  239. vpu_cfg_writel(vpu,
  240. vpu_cfg_readl(vpu, VPU_WDT_REG) | (1L << 31),
  241. VPU_WDT_REG);
  242. mutex_unlock(&vpu->vpu_mutex);
  243. return ret;
  244. }
  245. int vpu_ipi_register(struct platform_device *pdev,
  246. enum ipi_id id, ipi_handler_t handler,
  247. const char *name, void *priv)
  248. {
  249. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  250. struct vpu_ipi_desc *ipi_desc;
  251. if (!vpu) {
  252. dev_err(&pdev->dev, "vpu device in not ready\n");
  253. return -EPROBE_DEFER;
  254. }
  255. if (id >= 0 && id < IPI_MAX && handler) {
  256. ipi_desc = vpu->ipi_desc;
  257. ipi_desc[id].name = name;
  258. ipi_desc[id].handler = handler;
  259. ipi_desc[id].priv = priv;
  260. return 0;
  261. }
  262. dev_err(&pdev->dev, "register vpu ipi id %d with invalid arguments\n",
  263. id);
  264. return -EINVAL;
  265. }
  266. EXPORT_SYMBOL_GPL(vpu_ipi_register);
  267. int vpu_ipi_send(struct platform_device *pdev,
  268. enum ipi_id id, void *buf,
  269. unsigned int len)
  270. {
  271. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  272. struct share_obj *send_obj = vpu->send_buf;
  273. unsigned long timeout;
  274. int ret = 0;
  275. if (id <= IPI_VPU_INIT || id >= IPI_MAX ||
  276. len > sizeof(send_obj->share_buf) || !buf) {
  277. dev_err(vpu->dev, "failed to send ipi message\n");
  278. return -EINVAL;
  279. }
  280. ret = vpu_clock_enable(vpu);
  281. if (ret) {
  282. dev_err(vpu->dev, "failed to enable vpu clock\n");
  283. return ret;
  284. }
  285. if (!vpu_running(vpu)) {
  286. dev_err(vpu->dev, "vpu_ipi_send: VPU is not running\n");
  287. ret = -EINVAL;
  288. goto clock_disable;
  289. }
  290. mutex_lock(&vpu->vpu_mutex);
  291. /* Wait until VPU receives the last command */
  292. timeout = jiffies + msecs_to_jiffies(IPI_TIMEOUT_MS);
  293. do {
  294. if (time_after(jiffies, timeout)) {
  295. dev_err(vpu->dev, "vpu_ipi_send: IPI timeout!\n");
  296. ret = -EIO;
  297. goto mut_unlock;
  298. }
  299. } while (vpu_cfg_readl(vpu, HOST_TO_VPU));
  300. memcpy((void *)send_obj->share_buf, buf, len);
  301. send_obj->len = len;
  302. send_obj->id = id;
  303. vpu->ipi_id_ack[id] = false;
  304. /* send the command to VPU */
  305. vpu_cfg_writel(vpu, 0x1, HOST_TO_VPU);
  306. mutex_unlock(&vpu->vpu_mutex);
  307. /* wait for VPU's ACK */
  308. timeout = msecs_to_jiffies(IPI_TIMEOUT_MS);
  309. ret = wait_event_timeout(vpu->ack_wq, vpu->ipi_id_ack[id], timeout);
  310. vpu->ipi_id_ack[id] = false;
  311. if (ret == 0) {
  312. dev_err(vpu->dev, "vpu ipi %d ack time out !", id);
  313. ret = -EIO;
  314. goto clock_disable;
  315. }
  316. vpu_clock_disable(vpu);
  317. return 0;
  318. mut_unlock:
  319. mutex_unlock(&vpu->vpu_mutex);
  320. clock_disable:
  321. vpu_clock_disable(vpu);
  322. return ret;
  323. }
  324. EXPORT_SYMBOL_GPL(vpu_ipi_send);
  325. static void vpu_wdt_reset_func(struct work_struct *ws)
  326. {
  327. struct vpu_wdt *wdt = container_of(ws, struct vpu_wdt, ws);
  328. struct mtk_vpu *vpu = container_of(wdt, struct mtk_vpu, wdt);
  329. struct vpu_wdt_handler *handler = wdt->handler;
  330. int index, ret;
  331. dev_info(vpu->dev, "vpu reset\n");
  332. ret = vpu_clock_enable(vpu);
  333. if (ret) {
  334. dev_err(vpu->dev, "[VPU] wdt enables clock failed %d\n", ret);
  335. return;
  336. }
  337. mutex_lock(&vpu->vpu_mutex);
  338. vpu_cfg_writel(vpu, 0x0, VPU_RESET);
  339. vpu->fw_loaded = false;
  340. mutex_unlock(&vpu->vpu_mutex);
  341. vpu_clock_disable(vpu);
  342. for (index = 0; index < VPU_RST_MAX; index++) {
  343. if (handler[index].reset_func) {
  344. handler[index].reset_func(handler[index].priv);
  345. dev_dbg(vpu->dev, "wdt handler func %d\n", index);
  346. }
  347. }
  348. }
  349. int vpu_wdt_reg_handler(struct platform_device *pdev,
  350. void wdt_reset(void *),
  351. void *priv, enum rst_id id)
  352. {
  353. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  354. struct vpu_wdt_handler *handler;
  355. if (!vpu) {
  356. dev_err(&pdev->dev, "vpu device in not ready\n");
  357. return -EPROBE_DEFER;
  358. }
  359. handler = vpu->wdt.handler;
  360. if (id >= 0 && id < VPU_RST_MAX && wdt_reset) {
  361. dev_dbg(vpu->dev, "wdt register id %d\n", id);
  362. mutex_lock(&vpu->vpu_mutex);
  363. handler[id].reset_func = wdt_reset;
  364. handler[id].priv = priv;
  365. mutex_unlock(&vpu->vpu_mutex);
  366. return 0;
  367. }
  368. dev_err(vpu->dev, "register vpu wdt handler failed\n");
  369. return -EINVAL;
  370. }
  371. EXPORT_SYMBOL_GPL(vpu_wdt_reg_handler);
  372. unsigned int vpu_get_vdec_hw_capa(struct platform_device *pdev)
  373. {
  374. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  375. return vpu->run.dec_capability;
  376. }
  377. EXPORT_SYMBOL_GPL(vpu_get_vdec_hw_capa);
  378. unsigned int vpu_get_venc_hw_capa(struct platform_device *pdev)
  379. {
  380. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  381. return vpu->run.enc_capability;
  382. }
  383. EXPORT_SYMBOL_GPL(vpu_get_venc_hw_capa);
  384. void *vpu_mapping_dm_addr(struct platform_device *pdev,
  385. u32 dtcm_dmem_addr)
  386. {
  387. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  388. if (!dtcm_dmem_addr ||
  389. (dtcm_dmem_addr > (VPU_DTCM_SIZE + VPU_EXT_D_SIZE))) {
  390. dev_err(vpu->dev, "invalid virtual data memory address\n");
  391. return ERR_PTR(-EINVAL);
  392. }
  393. if (dtcm_dmem_addr < VPU_DTCM_SIZE)
  394. return (__force void *)(dtcm_dmem_addr + vpu->reg.tcm +
  395. VPU_DTCM_OFFSET);
  396. return vpu->extmem[D_FW].va + (dtcm_dmem_addr - VPU_DTCM_SIZE);
  397. }
  398. EXPORT_SYMBOL_GPL(vpu_mapping_dm_addr);
  399. struct platform_device *vpu_get_plat_device(struct platform_device *pdev)
  400. {
  401. struct device *dev = &pdev->dev;
  402. struct device_node *vpu_node;
  403. struct platform_device *vpu_pdev;
  404. vpu_node = of_parse_phandle(dev->of_node, "mediatek,vpu", 0);
  405. if (!vpu_node) {
  406. dev_err(dev, "can't get vpu node\n");
  407. return NULL;
  408. }
  409. vpu_pdev = of_find_device_by_node(vpu_node);
  410. if (WARN_ON(!vpu_pdev)) {
  411. dev_err(dev, "vpu pdev failed\n");
  412. of_node_put(vpu_node);
  413. return NULL;
  414. }
  415. return vpu_pdev;
  416. }
  417. EXPORT_SYMBOL_GPL(vpu_get_plat_device);
  418. /* load vpu program/data memory */
  419. static int load_requested_vpu(struct mtk_vpu *vpu,
  420. const struct firmware *vpu_fw,
  421. u8 fw_type)
  422. {
  423. size_t tcm_size = fw_type ? VPU_DTCM_SIZE : VPU_PTCM_SIZE;
  424. size_t fw_size = fw_type ? VPU_D_FW_SIZE : VPU_P_FW_SIZE;
  425. char *fw_name = fw_type ? VPU_D_FW : VPU_P_FW;
  426. size_t dl_size = 0;
  427. size_t extra_fw_size = 0;
  428. void *dest;
  429. int ret;
  430. ret = request_firmware(&vpu_fw, fw_name, vpu->dev);
  431. if (ret < 0) {
  432. dev_err(vpu->dev, "Failed to load %s, %d\n", fw_name, ret);
  433. return ret;
  434. }
  435. dl_size = vpu_fw->size;
  436. if (dl_size > fw_size) {
  437. dev_err(vpu->dev, "fw %s size %zu is abnormal\n", fw_name,
  438. dl_size);
  439. release_firmware(vpu_fw);
  440. return -EFBIG;
  441. }
  442. dev_dbg(vpu->dev, "Downloaded fw %s size: %zu.\n",
  443. fw_name,
  444. dl_size);
  445. /* reset VPU */
  446. vpu_cfg_writel(vpu, 0x0, VPU_RESET);
  447. /* handle extended firmware size */
  448. if (dl_size > tcm_size) {
  449. dev_dbg(vpu->dev, "fw size %zu > limited fw size %zu\n",
  450. dl_size, tcm_size);
  451. extra_fw_size = dl_size - tcm_size;
  452. dev_dbg(vpu->dev, "extra_fw_size %zu\n", extra_fw_size);
  453. dl_size = tcm_size;
  454. }
  455. dest = (__force void *)vpu->reg.tcm;
  456. if (fw_type == D_FW)
  457. dest += VPU_DTCM_OFFSET;
  458. memcpy(dest, vpu_fw->data, dl_size);
  459. /* download to extended memory if need */
  460. if (extra_fw_size > 0) {
  461. dest = vpu->extmem[fw_type].va;
  462. dev_dbg(vpu->dev, "download extended memory type %x\n",
  463. fw_type);
  464. memcpy(dest, vpu_fw->data + tcm_size, extra_fw_size);
  465. }
  466. release_firmware(vpu_fw);
  467. return 0;
  468. }
  469. int vpu_load_firmware(struct platform_device *pdev)
  470. {
  471. struct mtk_vpu *vpu;
  472. struct device *dev = &pdev->dev;
  473. struct vpu_run *run;
  474. const struct firmware *vpu_fw = NULL;
  475. int ret;
  476. if (!pdev) {
  477. dev_err(dev, "VPU platform device is invalid\n");
  478. return -EINVAL;
  479. }
  480. vpu = platform_get_drvdata(pdev);
  481. run = &vpu->run;
  482. mutex_lock(&vpu->vpu_mutex);
  483. if (vpu->fw_loaded) {
  484. mutex_unlock(&vpu->vpu_mutex);
  485. return 0;
  486. }
  487. mutex_unlock(&vpu->vpu_mutex);
  488. ret = vpu_clock_enable(vpu);
  489. if (ret) {
  490. dev_err(dev, "enable clock failed %d\n", ret);
  491. return ret;
  492. }
  493. mutex_lock(&vpu->vpu_mutex);
  494. run->signaled = false;
  495. dev_dbg(vpu->dev, "firmware request\n");
  496. /* Downloading program firmware to device*/
  497. ret = load_requested_vpu(vpu, vpu_fw, P_FW);
  498. if (ret < 0) {
  499. dev_err(dev, "Failed to request %s, %d\n", VPU_P_FW, ret);
  500. goto OUT_LOAD_FW;
  501. }
  502. /* Downloading data firmware to device */
  503. ret = load_requested_vpu(vpu, vpu_fw, D_FW);
  504. if (ret < 0) {
  505. dev_err(dev, "Failed to request %s, %d\n", VPU_D_FW, ret);
  506. goto OUT_LOAD_FW;
  507. }
  508. vpu->fw_loaded = true;
  509. /* boot up vpu */
  510. vpu_cfg_writel(vpu, 0x1, VPU_RESET);
  511. ret = wait_event_interruptible_timeout(run->wq,
  512. run->signaled,
  513. msecs_to_jiffies(INIT_TIMEOUT_MS)
  514. );
  515. if (ret == 0) {
  516. ret = -ETIME;
  517. dev_err(dev, "wait vpu initialization timout!\n");
  518. goto OUT_LOAD_FW;
  519. } else if (-ERESTARTSYS == ret) {
  520. dev_err(dev, "wait vpu interrupted by a signal!\n");
  521. goto OUT_LOAD_FW;
  522. }
  523. ret = 0;
  524. dev_info(dev, "vpu is ready. Fw version %s\n", run->fw_ver);
  525. OUT_LOAD_FW:
  526. mutex_unlock(&vpu->vpu_mutex);
  527. vpu_clock_disable(vpu);
  528. return ret;
  529. }
  530. EXPORT_SYMBOL_GPL(vpu_load_firmware);
  531. static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
  532. {
  533. struct mtk_vpu *vpu = (struct mtk_vpu *)priv;
  534. struct vpu_run *run = (struct vpu_run *)data;
  535. vpu->run.signaled = run->signaled;
  536. strncpy(vpu->run.fw_ver, run->fw_ver, VPU_FW_VER_LEN);
  537. vpu->run.dec_capability = run->dec_capability;
  538. vpu->run.enc_capability = run->enc_capability;
  539. wake_up_interruptible(&vpu->run.wq);
  540. }
  541. #ifdef CONFIG_DEBUG_FS
  542. static ssize_t vpu_debug_read(struct file *file, char __user *user_buf,
  543. size_t count, loff_t *ppos)
  544. {
  545. char buf[256];
  546. unsigned int len;
  547. unsigned int running, pc, vpu_to_host, host_to_vpu, wdt;
  548. int ret;
  549. struct device *dev = file->private_data;
  550. struct mtk_vpu *vpu = dev_get_drvdata(dev);
  551. ret = vpu_clock_enable(vpu);
  552. if (ret) {
  553. dev_err(vpu->dev, "[VPU] enable clock failed %d\n", ret);
  554. return 0;
  555. }
  556. /* vpu register status */
  557. running = vpu_running(vpu);
  558. pc = vpu_cfg_readl(vpu, VPU_PC_REG);
  559. wdt = vpu_cfg_readl(vpu, VPU_WDT_REG);
  560. host_to_vpu = vpu_cfg_readl(vpu, HOST_TO_VPU);
  561. vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
  562. vpu_clock_disable(vpu);
  563. if (running) {
  564. len = snprintf(buf, sizeof(buf), "VPU is running\n\n"
  565. "FW Version: %s\n"
  566. "PC: 0x%x\n"
  567. "WDT: 0x%x\n"
  568. "Host to VPU: 0x%x\n"
  569. "VPU to Host: 0x%x\n",
  570. vpu->run.fw_ver, pc, wdt,
  571. host_to_vpu, vpu_to_host);
  572. } else {
  573. len = snprintf(buf, sizeof(buf), "VPU not running\n");
  574. }
  575. return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  576. }
  577. static const struct file_operations vpu_debug_fops = {
  578. .open = simple_open,
  579. .read = vpu_debug_read,
  580. };
  581. #endif /* CONFIG_DEBUG_FS */
  582. static void vpu_free_ext_mem(struct mtk_vpu *vpu, u8 fw_type)
  583. {
  584. struct device *dev = vpu->dev;
  585. size_t fw_ext_size = fw_type ? VPU_EXT_D_SIZE : VPU_EXT_P_SIZE;
  586. dma_free_coherent(dev, fw_ext_size, vpu->extmem[fw_type].va,
  587. vpu->extmem[fw_type].pa);
  588. }
  589. static int vpu_alloc_ext_mem(struct mtk_vpu *vpu, u32 fw_type)
  590. {
  591. struct device *dev = vpu->dev;
  592. size_t fw_ext_size = fw_type ? VPU_EXT_D_SIZE : VPU_EXT_P_SIZE;
  593. u32 vpu_ext_mem0 = fw_type ? VPU_DMEM_EXT0_ADDR : VPU_PMEM_EXT0_ADDR;
  594. u32 vpu_ext_mem1 = fw_type ? VPU_DMEM_EXT1_ADDR : VPU_PMEM_EXT1_ADDR;
  595. u32 offset_4gb = vpu->enable_4GB ? 0x40000000 : 0;
  596. vpu->extmem[fw_type].va = dma_alloc_coherent(dev,
  597. fw_ext_size,
  598. &vpu->extmem[fw_type].pa,
  599. GFP_KERNEL);
  600. if (!vpu->extmem[fw_type].va) {
  601. dev_err(dev, "Failed to allocate the extended program memory\n");
  602. return -ENOMEM;
  603. }
  604. /* Disable extend0. Enable extend1 */
  605. vpu_cfg_writel(vpu, 0x1, vpu_ext_mem0);
  606. vpu_cfg_writel(vpu, (vpu->extmem[fw_type].pa & 0xFFFFF000) + offset_4gb,
  607. vpu_ext_mem1);
  608. dev_info(dev, "%s extend memory phy=0x%llx virt=0x%p\n",
  609. fw_type ? "Data" : "Program",
  610. (unsigned long long)vpu->extmem[fw_type].pa,
  611. vpu->extmem[fw_type].va);
  612. return 0;
  613. }
  614. static void vpu_ipi_handler(struct mtk_vpu *vpu)
  615. {
  616. struct share_obj *rcv_obj = vpu->recv_buf;
  617. struct vpu_ipi_desc *ipi_desc = vpu->ipi_desc;
  618. if (rcv_obj->id < IPI_MAX && ipi_desc[rcv_obj->id].handler) {
  619. ipi_desc[rcv_obj->id].handler(rcv_obj->share_buf,
  620. rcv_obj->len,
  621. ipi_desc[rcv_obj->id].priv);
  622. if (rcv_obj->id > IPI_VPU_INIT) {
  623. vpu->ipi_id_ack[rcv_obj->id] = true;
  624. wake_up(&vpu->ack_wq);
  625. }
  626. } else {
  627. dev_err(vpu->dev, "No such ipi id = %d\n", rcv_obj->id);
  628. }
  629. }
  630. static int vpu_ipi_init(struct mtk_vpu *vpu)
  631. {
  632. /* Disable VPU to host interrupt */
  633. vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
  634. /* shared buffer initialization */
  635. vpu->recv_buf = (__force struct share_obj *)(vpu->reg.tcm +
  636. VPU_DTCM_OFFSET);
  637. vpu->send_buf = vpu->recv_buf + 1;
  638. memset(vpu->recv_buf, 0, sizeof(struct share_obj));
  639. memset(vpu->send_buf, 0, sizeof(struct share_obj));
  640. return 0;
  641. }
  642. static irqreturn_t vpu_irq_handler(int irq, void *priv)
  643. {
  644. struct mtk_vpu *vpu = priv;
  645. u32 vpu_to_host;
  646. int ret;
  647. /*
  648. * Clock should have been enabled already.
  649. * Enable again in case vpu_ipi_send times out
  650. * and has disabled the clock.
  651. */
  652. ret = clk_enable(vpu->clk);
  653. if (ret) {
  654. dev_err(vpu->dev, "[VPU] enable clock failed %d\n", ret);
  655. return IRQ_NONE;
  656. }
  657. vpu_to_host = vpu_cfg_readl(vpu, VPU_TO_HOST);
  658. if (vpu_to_host & VPU_IPC_INT) {
  659. vpu_ipi_handler(vpu);
  660. } else {
  661. dev_err(vpu->dev, "vpu watchdog timeout! 0x%x", vpu_to_host);
  662. queue_work(vpu->wdt.wq, &vpu->wdt.ws);
  663. }
  664. /* VPU won't send another interrupt until we set VPU_TO_HOST to 0. */
  665. vpu_cfg_writel(vpu, 0x0, VPU_TO_HOST);
  666. clk_disable(vpu->clk);
  667. return IRQ_HANDLED;
  668. }
  669. #ifdef CONFIG_DEBUG_FS
  670. static struct dentry *vpu_debugfs;
  671. #endif
  672. static int mtk_vpu_probe(struct platform_device *pdev)
  673. {
  674. struct mtk_vpu *vpu;
  675. struct device *dev;
  676. struct resource *res;
  677. int ret = 0;
  678. dev_dbg(&pdev->dev, "initialization\n");
  679. dev = &pdev->dev;
  680. vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
  681. if (!vpu)
  682. return -ENOMEM;
  683. vpu->dev = &pdev->dev;
  684. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tcm");
  685. vpu->reg.tcm = devm_ioremap_resource(dev, res);
  686. if (IS_ERR((__force void *)vpu->reg.tcm))
  687. return PTR_ERR((__force void *)vpu->reg.tcm);
  688. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_reg");
  689. vpu->reg.cfg = devm_ioremap_resource(dev, res);
  690. if (IS_ERR((__force void *)vpu->reg.cfg))
  691. return PTR_ERR((__force void *)vpu->reg.cfg);
  692. /* Get VPU clock */
  693. vpu->clk = devm_clk_get(dev, "main");
  694. if (IS_ERR(vpu->clk)) {
  695. dev_err(dev, "get vpu clock failed\n");
  696. return PTR_ERR(vpu->clk);
  697. }
  698. platform_set_drvdata(pdev, vpu);
  699. ret = clk_prepare(vpu->clk);
  700. if (ret) {
  701. dev_err(dev, "prepare vpu clock failed\n");
  702. return ret;
  703. }
  704. /* VPU watchdog */
  705. vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt");
  706. if (!vpu->wdt.wq) {
  707. dev_err(dev, "initialize wdt workqueue failed\n");
  708. return -ENOMEM;
  709. }
  710. INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func);
  711. mutex_init(&vpu->vpu_mutex);
  712. ret = vpu_clock_enable(vpu);
  713. if (ret) {
  714. dev_err(dev, "enable vpu clock failed\n");
  715. goto workqueue_destroy;
  716. }
  717. dev_dbg(dev, "vpu ipi init\n");
  718. ret = vpu_ipi_init(vpu);
  719. if (ret) {
  720. dev_err(dev, "Failed to init ipi\n");
  721. goto disable_vpu_clk;
  722. }
  723. /* register vpu initialization IPI */
  724. ret = vpu_ipi_register(pdev, IPI_VPU_INIT, vpu_init_ipi_handler,
  725. "vpu_init", vpu);
  726. if (ret) {
  727. dev_err(dev, "Failed to register IPI_VPU_INIT\n");
  728. goto vpu_mutex_destroy;
  729. }
  730. #ifdef CONFIG_DEBUG_FS
  731. vpu_debugfs = debugfs_create_file("mtk_vpu", S_IRUGO, NULL, (void *)dev,
  732. &vpu_debug_fops);
  733. if (!vpu_debugfs) {
  734. ret = -ENOMEM;
  735. goto cleanup_ipi;
  736. }
  737. #endif
  738. /* Set PTCM to 96K and DTCM to 32K */
  739. vpu_cfg_writel(vpu, 0x2, VPU_TCM_CFG);
  740. vpu->enable_4GB = !!(totalram_pages > (SZ_2G >> PAGE_SHIFT));
  741. dev_info(dev, "4GB mode %u\n", vpu->enable_4GB);
  742. if (vpu->enable_4GB) {
  743. ret = of_reserved_mem_device_init(dev);
  744. if (ret)
  745. dev_info(dev, "init reserved memory failed\n");
  746. /* continue to use dynamic allocation if failed */
  747. }
  748. ret = vpu_alloc_ext_mem(vpu, D_FW);
  749. if (ret) {
  750. dev_err(dev, "Allocate DM failed\n");
  751. goto remove_debugfs;
  752. }
  753. ret = vpu_alloc_ext_mem(vpu, P_FW);
  754. if (ret) {
  755. dev_err(dev, "Allocate PM failed\n");
  756. goto free_d_mem;
  757. }
  758. init_waitqueue_head(&vpu->run.wq);
  759. init_waitqueue_head(&vpu->ack_wq);
  760. res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  761. if (!res) {
  762. dev_err(dev, "get IRQ resource failed.\n");
  763. ret = -ENXIO;
  764. goto free_p_mem;
  765. }
  766. vpu->reg.irq = platform_get_irq(pdev, 0);
  767. ret = devm_request_irq(dev, vpu->reg.irq, vpu_irq_handler, 0,
  768. pdev->name, vpu);
  769. if (ret) {
  770. dev_err(dev, "failed to request irq\n");
  771. goto free_p_mem;
  772. }
  773. vpu_clock_disable(vpu);
  774. dev_dbg(dev, "initialization completed\n");
  775. return 0;
  776. free_p_mem:
  777. vpu_free_ext_mem(vpu, P_FW);
  778. free_d_mem:
  779. vpu_free_ext_mem(vpu, D_FW);
  780. remove_debugfs:
  781. of_reserved_mem_device_release(dev);
  782. #ifdef CONFIG_DEBUG_FS
  783. debugfs_remove(vpu_debugfs);
  784. cleanup_ipi:
  785. #endif
  786. memset(vpu->ipi_desc, 0, sizeof(struct vpu_ipi_desc) * IPI_MAX);
  787. vpu_mutex_destroy:
  788. mutex_destroy(&vpu->vpu_mutex);
  789. disable_vpu_clk:
  790. vpu_clock_disable(vpu);
  791. workqueue_destroy:
  792. destroy_workqueue(vpu->wdt.wq);
  793. return ret;
  794. }
  795. static const struct of_device_id mtk_vpu_match[] = {
  796. {
  797. .compatible = "mediatek,mt8173-vpu",
  798. },
  799. {},
  800. };
  801. MODULE_DEVICE_TABLE(of, mtk_vpu_match);
  802. static int mtk_vpu_remove(struct platform_device *pdev)
  803. {
  804. struct mtk_vpu *vpu = platform_get_drvdata(pdev);
  805. #ifdef CONFIG_DEBUG_FS
  806. debugfs_remove(vpu_debugfs);
  807. #endif
  808. if (vpu->wdt.wq) {
  809. flush_workqueue(vpu->wdt.wq);
  810. destroy_workqueue(vpu->wdt.wq);
  811. }
  812. vpu_free_ext_mem(vpu, P_FW);
  813. vpu_free_ext_mem(vpu, D_FW);
  814. mutex_destroy(&vpu->vpu_mutex);
  815. clk_unprepare(vpu->clk);
  816. return 0;
  817. }
  818. static struct platform_driver mtk_vpu_driver = {
  819. .probe = mtk_vpu_probe,
  820. .remove = mtk_vpu_remove,
  821. .driver = {
  822. .name = "mtk_vpu",
  823. .of_match_table = mtk_vpu_match,
  824. },
  825. };
  826. module_platform_driver(mtk_vpu_driver);
  827. MODULE_LICENSE("GPL v2");
  828. MODULE_DESCRIPTION("Mediatek Video Prosessor Unit driver");