Commit | Line | Data |
---|---|---|
1802d0be | 1 | // SPDX-License-Identifier: GPL-2.0-only |
c8eb2d7e MT |
2 | /* |
3 | * Copyright (c) 2015-2016 MediaTek Inc. | |
4 | * Author: Houlong Wei <houlong.wei@mediatek.com> | |
5 | * Ming Hsiu Tsai <minghsiu.tsai@mediatek.com> | |
c8eb2d7e MT |
6 | */ |
7 | ||
8 | #include "mtk_mdp_core.h" | |
9 | #include "mtk_mdp_vpu.h" | |
10 | #include "mtk_vpu.h" | |
11 | ||
12 | ||
13 | static inline struct mtk_mdp_ctx *vpu_to_ctx(struct mtk_mdp_vpu *vpu) | |
14 | { | |
15 | return container_of(vpu, struct mtk_mdp_ctx, vpu); | |
16 | } | |
17 | ||
e6599adf | 18 | static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg) |
c8eb2d7e | 19 | { |
37bf7e34 MT |
20 | struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *) |
21 | (unsigned long)msg->ap_inst; | |
c8eb2d7e MT |
22 | |
23 | /* mapping VPU address to kernel virtual address */ | |
24 | vpu->vsi = (struct mdp_process_vsi *) | |
25 | vpu_mapping_dm_addr(vpu->pdev, msg->vpu_inst_addr); | |
26 | vpu->inst_addr = msg->vpu_inst_addr; | |
27 | } | |
28 | ||
e6599adf HYW |
29 | static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len, |
30 | void *priv) | |
c8eb2d7e | 31 | { |
e6599adf HYW |
32 | const struct mdp_ipi_comm_ack *msg = data; |
33 | unsigned int msg_id = msg->msg_id; | |
37bf7e34 MT |
34 | struct mtk_mdp_vpu *vpu = (struct mtk_mdp_vpu *) |
35 | (unsigned long)msg->ap_inst; | |
c8eb2d7e MT |
36 | struct mtk_mdp_ctx *ctx; |
37 | ||
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 | ||
61 | int mtk_mdp_vpu_register(struct platform_device *pdev) | |
62 | { | |
63 | struct mtk_mdp_dev *mdp = platform_get_drvdata(pdev); | |
64 | int err; | |
65 | ||
66 | err = vpu_ipi_register(mdp->vpu_dev, IPI_MDP, | |
67 | mtk_mdp_vpu_ipi_handler, "mdp_vpu", NULL); | |
68 | if (err) | |
69 | dev_err(&mdp->pdev->dev, | |
70 | "vpu_ipi_registration fail status=%d\n", err); | |
71 | ||
72 | return err; | |
73 | } | |
74 | ||
75 | static int mtk_mdp_vpu_send_msg(void *msg, int len, struct mtk_mdp_vpu *vpu, | |
76 | int id) | |
77 | { | |
78 | struct mtk_mdp_ctx *ctx = vpu_to_ctx(vpu); | |
79 | int err; | |
80 | ||
81 | if (!vpu->pdev) { | |
82 | mtk_mdp_dbg(1, "[%d]:vpu pdev is NULL", ctx->id); | |
83 | return -EINVAL; | |
84 | } | |
85 | ||
86 | mutex_lock(&ctx->mdp_dev->vpulock); | |
87 | err = vpu_ipi_send(vpu->pdev, (enum ipi_id)id, msg, len); | |
669c6141 | 88 | if (err) |
c8eb2d7e MT |
89 | dev_err(&ctx->mdp_dev->pdev->dev, |
90 | "vpu_ipi_send fail status %d\n", err); | |
c8eb2d7e MT |
91 | mutex_unlock(&ctx->mdp_dev->vpulock); |
92 | ||
93 | return err; | |
94 | } | |
95 | ||
96 | static int mtk_mdp_vpu_send_ap_ipi(struct mtk_mdp_vpu *vpu, uint32_t msg_id) | |
97 | { | |
98 | int err; | |
99 | struct mdp_ipi_comm msg; | |
100 | ||
101 | msg.msg_id = msg_id; | |
102 | msg.ipi_id = IPI_MDP; | |
103 | msg.vpu_inst_addr = vpu->inst_addr; | |
37bf7e34 | 104 | msg.ap_inst = (unsigned long)vpu; |
c8eb2d7e MT |
105 | err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP); |
106 | if (!err && vpu->failure) | |
107 | err = -EINVAL; | |
108 | ||
109 | return err; | |
110 | } | |
111 | ||
112 | int mtk_mdp_vpu_init(struct mtk_mdp_vpu *vpu) | |
113 | { | |
114 | int err; | |
115 | struct mdp_ipi_init msg; | |
116 | struct mtk_mdp_ctx *ctx = vpu_to_ctx(vpu); | |
117 | ||
118 | vpu->pdev = ctx->mdp_dev->vpu_dev; | |
119 | ||
120 | msg.msg_id = AP_MDP_INIT; | |
121 | msg.ipi_id = IPI_MDP; | |
37bf7e34 | 122 | msg.ap_inst = (unsigned long)vpu; |
c8eb2d7e MT |
123 | err = mtk_mdp_vpu_send_msg((void *)&msg, sizeof(msg), vpu, IPI_MDP); |
124 | if (!err && vpu->failure) | |
125 | err = -EINVAL; | |
126 | ||
127 | return err; | |
128 | } | |
129 | ||
130 | int mtk_mdp_vpu_deinit(struct mtk_mdp_vpu *vpu) | |
131 | { | |
132 | return mtk_mdp_vpu_send_ap_ipi(vpu, AP_MDP_DEINIT); | |
133 | } | |
134 | ||
135 | int mtk_mdp_vpu_process(struct mtk_mdp_vpu *vpu) | |
136 | { | |
137 | return mtk_mdp_vpu_send_ap_ipi(vpu, AP_MDP_PROCESS); | |
138 | } |