1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: PC Chen <pc.chen@mediatek.com>
7 #include "mtk_vcodec_drv.h"
8 #include "mtk_vcodec_util.h"
9 #include "vdec_ipi_msg.h"
10 #include "vdec_vpu_if.h"
11 #include "mtk_vcodec_fw.h"
13 static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack
*msg
)
15 struct vdec_vpu_inst
*vpu
= (struct vdec_vpu_inst
*)
16 (unsigned long)msg
->ap_inst_addr
;
18 mtk_vcodec_debug(vpu
, "+ ap_inst_addr = 0x%llx", msg
->ap_inst_addr
);
20 /* mapping VPU address to kernel virtual address */
21 /* the content in vsi is initialized to 0 in VPU */
22 vpu
->vsi
= mtk_vcodec_fw_map_dm_addr(vpu
->ctx
->dev
->fw_handler
,
24 vpu
->inst_addr
= msg
->vpu_inst_addr
;
26 mtk_vcodec_debug(vpu
, "- vpu_inst_addr = 0x%x", vpu
->inst_addr
);
30 * vpu_dec_ipi_handler - Handler for VPU ipi message.
33 * @len : length of ipi message
34 * @priv: callback private data which is passed by decoder when register.
36 * This function runs in interrupt context and it means there's an IPI MSG
39 static void vpu_dec_ipi_handler(void *data
, unsigned int len
, void *priv
)
41 const struct vdec_vpu_ipi_ack
*msg
= data
;
42 struct vdec_vpu_inst
*vpu
= (struct vdec_vpu_inst
*)
43 (unsigned long)msg
->ap_inst_addr
;
45 mtk_vcodec_debug(vpu
, "+ id=%X", msg
->msg_id
);
47 if (msg
->status
== 0) {
48 switch (msg
->msg_id
) {
49 case VPU_IPIMSG_DEC_INIT_ACK
:
50 handle_init_ack_msg(data
);
53 case VPU_IPIMSG_DEC_START_ACK
:
54 case VPU_IPIMSG_DEC_END_ACK
:
55 case VPU_IPIMSG_DEC_DEINIT_ACK
:
56 case VPU_IPIMSG_DEC_RESET_ACK
:
60 mtk_vcodec_err(vpu
, "invalid msg=%X", msg
->msg_id
);
65 mtk_vcodec_debug(vpu
, "- id=%X", msg
->msg_id
);
66 vpu
->failure
= msg
->status
;
70 static int vcodec_vpu_send_msg(struct vdec_vpu_inst
*vpu
, void *msg
, int len
)
74 mtk_vcodec_debug(vpu
, "id=%X", *(uint32_t *)msg
);
79 err
= mtk_vcodec_fw_ipi_send(vpu
->ctx
->dev
->fw_handler
, vpu
->id
, msg
,
82 mtk_vcodec_err(vpu
, "send fail vpu_id=%d msg_id=%X status=%d",
83 vpu
->id
, *(uint32_t *)msg
, err
);
90 static int vcodec_send_ap_ipi(struct vdec_vpu_inst
*vpu
, unsigned int msg_id
)
92 struct vdec_ap_ipi_cmd msg
;
95 mtk_vcodec_debug(vpu
, "+ id=%X", msg_id
);
97 memset(&msg
, 0, sizeof(msg
));
99 msg
.vpu_inst_addr
= vpu
->inst_addr
;
101 err
= vcodec_vpu_send_msg(vpu
, &msg
, sizeof(msg
));
102 mtk_vcodec_debug(vpu
, "- id=%X ret=%d", msg_id
, err
);
106 int vpu_dec_init(struct vdec_vpu_inst
*vpu
)
108 struct vdec_ap_ipi_init msg
;
111 mtk_vcodec_debug_enter(vpu
);
113 init_waitqueue_head(&vpu
->wq
);
114 vpu
->handler
= vpu_dec_ipi_handler
;
116 err
= mtk_vcodec_fw_ipi_register(vpu
->ctx
->dev
->fw_handler
, vpu
->id
,
117 vpu
->handler
, "vdec", NULL
);
119 mtk_vcodec_err(vpu
, "vpu_ipi_register fail status=%d", err
);
123 memset(&msg
, 0, sizeof(msg
));
124 msg
.msg_id
= AP_IPIMSG_DEC_INIT
;
125 msg
.ap_inst_addr
= (unsigned long)vpu
;
127 mtk_vcodec_debug(vpu
, "vdec_inst=%p", vpu
);
129 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
130 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
134 int vpu_dec_start(struct vdec_vpu_inst
*vpu
, uint32_t *data
, unsigned int len
)
136 struct vdec_ap_ipi_dec_start msg
;
140 mtk_vcodec_debug_enter(vpu
);
142 if (len
> ARRAY_SIZE(msg
.data
)) {
143 mtk_vcodec_err(vpu
, "invalid len = %d\n", len
);
147 memset(&msg
, 0, sizeof(msg
));
148 msg
.msg_id
= AP_IPIMSG_DEC_START
;
149 msg
.vpu_inst_addr
= vpu
->inst_addr
;
151 for (i
= 0; i
< len
; i
++)
152 msg
.data
[i
] = data
[i
];
154 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
155 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
159 int vpu_dec_end(struct vdec_vpu_inst
*vpu
)
161 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_END
);
164 int vpu_dec_deinit(struct vdec_vpu_inst
*vpu
)
166 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_DEINIT
);
169 int vpu_dec_reset(struct vdec_vpu_inst
*vpu
)
171 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_RESET
);