mtk_mdp_vpu.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Copyright (c) 2015-2016 MediaTek Inc.
  3. * Author: Houlong Wei <houlong.wei@mediatek.com>
  4. * Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #include "mtk_mdp_core.h"
  16. #include "mtk_mdp_vpu.h"
  17. #include "mtk_vpu.h"
  18. static inline struct mtk_mdp_ctx *vpu_to_ctx(struct mtk_mdp_vpu *vpu)
  19. {
  20. return container_of(vpu, struct mtk_mdp_ctx, vpu);
  21. }
  22. static void mtk_mdp_vpu_handle_init_ack(struct mdp_ipi_comm_ack *msg)
  23. {
  24. struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)
  25. (unsigned long)msg->ap_inst;
  26. /* mapping VPU address to kernel virtual address */
  27. vpu->vsi = (struct mdp_process_vsi *)
  28. vpu_mapping_dm_addr(vpu->pdev, msg->vpu_inst_addr);
  29. vpu->inst_addr = msg->vpu_inst_addr;
  30. }
  31. static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len, void *priv)
  32. {
  33. unsigned int msg_id = *(unsigned int *)data;
  34. struct mdp_ipi_comm_ack *msg = (struct mdp_ipi_comm_ack *)data;
  35. struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *)
  36. (unsigned long)msg->ap_inst;
  37. struct mtk_mdp_ctx *ctx;
  38. vpu->failure = msg->status;
  39. if (!vpu->failure) {
  40. switch (msg_id) {
  41. case VPU_MDP_INIT_ACK:
  42. mtk_mdp_vpu_handle_init_ack(data);
  43. break;
  44. case VPU_MDP_DEINIT_ACK:
  45. case VPU_MDP_PROCESS_ACK:
  46. break;
  47. default:
  48. ctx = vpu_to_ctx(vpu);
  49. dev_err(&ctx->mdp_dev->pdev->dev,
  50. "handle unknown ipi msg:0x%x\n",
  51. msg_id);
  52. break;
  53. }
  54. } else {
  55. ctx = vpu_to_ctx(vpu);
  56. mtk_mdp_dbg(0, "[%d]:msg 0x%x, failure:%d", ctx->id,
  57. msg_id, vpu->failure);
  58. }
  59. }
  60. int mtk_mdp_vpu_register(struct platform_device *pdev)
  61. {
  62. struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev);
  63. int err;
  64. err = vpu_ipi_register(mdp->vpu_dev, IPI_MDP,
  65. mtk_mdp_vpu_ipi_handler, "mdp_vpu", NULL);
  66. if (err)
  67. dev_err(&mdp->pdev->dev,
  68. "vpu_ipi_registration fail status=%d\n", err);
  69. return err;
  70. }
  71. static int mtk_mdp_vpu_send_msg(void *msg, int len, struct mtk_mdp_vpu *vpu,
  72. int id)
  73. {
  74. struct mtk_mdp_ctx *ctx = vpu_to_ctx(vpu);
  75. int err;
  76. if (!vpu->pdev) {
  77. mtk_mdp_dbg(1, "[%d]:vpu pdev is NULL", ctx->id);
  78. return -EINVAL;
  79. }
  80. mutex_lock(&ctx->mdp_dev->vpulock);
  81. err = vpu_ipi_send(vpu->pdev, (enum ipi_id)id, msg, len);
  82. if (err)
  83. dev_err(&ctx->mdp_dev->pdev->dev,
  84. "vpu_ipi_send fail status %d\n", err);
  85. mutex_unlock(&ctx->mdp_dev->vpulock);
  86. return err;
  87. }
  88. static int mtk_mdp_vpu_send_ap_ipi(struct mtk_mdp_vpu *vpu, uint32_t msg_id)
  89. {
  90. int err;
  91. struct mdp_ipi_comm msg;
  92. msg.msg_id = msg_id;
  93. msg.ipi_id = IPI_MDP;
  94. msg.vpu_inst_addr = vpu->inst_addr;
  95. msg.ap_inst = (unsigned long)vpu;
  96. err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP);
  97. if (!err && vpu->failure)
  98. err = -EINVAL;
  99. return err;
  100. }
  101. int mtk_mdp_vpu_init(struct mtk_mdp_vpu *vpu)
  102. {
  103. int err;
  104. struct mdp_ipi_init msg;
  105. struct mtk_mdp_ctx *ctx = vpu_to_ctx(vpu);
  106. vpu->pdev = ctx->mdp_dev->vpu_dev;
  107. msg.msg_id = AP_MDP_INIT;
  108. msg.ipi_id = IPI_MDP;
  109. msg.ap_inst = (unsigned long)vpu;
  110. err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP);
  111. if (!err && vpu->failure)
  112. err = -EINVAL;
  113. return err;
  114. }
  115. int mtk_mdp_vpu_deinit(struct mtk_mdp_vpu *vpu)
  116. {
  117. return mtk_mdp_vpu_send_ap_ipi(vpu, AP_MDP_DEINIT);
  118. }
  119. int mtk_mdp_vpu_process(struct mtk_mdp_vpu *vpu)
  120. {
  121. return mtk_mdp_vpu_send_ap_ipi(vpu, AP_MDP_PROCESS);
  122. }