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"
12 static void handle_init_ack_msg(struct vdec_vpu_ipi_init_ack
*msg
)
14 struct vdec_vpu_inst
*vpu
= (struct vdec_vpu_inst
*)
15 (unsigned long)msg
->ap_inst_addr
;
17 mtk_vcodec_debug(vpu
, "+ ap_inst_addr = 0x%llx", msg
->ap_inst_addr
);
19 /* mapping VPU address to kernel virtual address */
20 /* the content in vsi is initialized to 0 in VPU */
21 vpu
->vsi
= vpu_mapping_dm_addr(vpu
->dev
, msg
->vpu_inst_addr
);
22 vpu
->inst_addr
= msg
->vpu_inst_addr
;
24 mtk_vcodec_debug(vpu
, "- vpu_inst_addr = 0x%x", vpu
->inst_addr
);
28 * vpu_dec_ipi_handler - Handler for VPU ipi message.
31 * @len : length of ipi message
32 * @priv: callback private data which is passed by decoder when register.
34 * This function runs in interrupt context and it means there's an IPI MSG
37 static void vpu_dec_ipi_handler(void *data
, unsigned int len
, void *priv
)
39 struct vdec_vpu_ipi_ack
*msg
= data
;
40 struct vdec_vpu_inst
*vpu
= (struct vdec_vpu_inst
*)
41 (unsigned long)msg
->ap_inst_addr
;
43 mtk_vcodec_debug(vpu
, "+ id=%X", msg
->msg_id
);
45 if (msg
->status
== 0) {
46 switch (msg
->msg_id
) {
47 case VPU_IPIMSG_DEC_INIT_ACK
:
48 handle_init_ack_msg(data
);
51 case VPU_IPIMSG_DEC_START_ACK
:
52 case VPU_IPIMSG_DEC_END_ACK
:
53 case VPU_IPIMSG_DEC_DEINIT_ACK
:
54 case VPU_IPIMSG_DEC_RESET_ACK
:
58 mtk_vcodec_err(vpu
, "invalid msg=%X", msg
->msg_id
);
63 mtk_vcodec_debug(vpu
, "- id=%X", msg
->msg_id
);
64 vpu
->failure
= msg
->status
;
68 static int vcodec_vpu_send_msg(struct vdec_vpu_inst
*vpu
, void *msg
, int len
)
72 mtk_vcodec_debug(vpu
, "id=%X", *(uint32_t *)msg
);
77 err
= vpu_ipi_send(vpu
->dev
, vpu
->id
, msg
, len
);
79 mtk_vcodec_err(vpu
, "send fail vpu_id=%d msg_id=%X status=%d",
80 vpu
->id
, *(uint32_t *)msg
, err
);
87 static int vcodec_send_ap_ipi(struct vdec_vpu_inst
*vpu
, unsigned int msg_id
)
89 struct vdec_ap_ipi_cmd msg
;
92 mtk_vcodec_debug(vpu
, "+ id=%X", msg_id
);
94 memset(&msg
, 0, sizeof(msg
));
96 msg
.vpu_inst_addr
= vpu
->inst_addr
;
98 err
= vcodec_vpu_send_msg(vpu
, &msg
, sizeof(msg
));
99 mtk_vcodec_debug(vpu
, "- id=%X ret=%d", msg_id
, err
);
103 int vpu_dec_init(struct vdec_vpu_inst
*vpu
)
105 struct vdec_ap_ipi_init msg
;
108 mtk_vcodec_debug_enter(vpu
);
110 init_waitqueue_head(&vpu
->wq
);
111 vpu
->handler
= vpu_dec_ipi_handler
;
113 err
= vpu_ipi_register(vpu
->dev
, vpu
->id
, vpu
->handler
, "vdec", NULL
);
115 mtk_vcodec_err(vpu
, "vpu_ipi_register fail status=%d", err
);
119 memset(&msg
, 0, sizeof(msg
));
120 msg
.msg_id
= AP_IPIMSG_DEC_INIT
;
121 msg
.ap_inst_addr
= (unsigned long)vpu
;
123 mtk_vcodec_debug(vpu
, "vdec_inst=%p", vpu
);
125 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
126 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
130 int vpu_dec_start(struct vdec_vpu_inst
*vpu
, uint32_t *data
, unsigned int len
)
132 struct vdec_ap_ipi_dec_start msg
;
136 mtk_vcodec_debug_enter(vpu
);
138 if (len
> ARRAY_SIZE(msg
.data
)) {
139 mtk_vcodec_err(vpu
, "invalid len = %d\n", len
);
143 memset(&msg
, 0, sizeof(msg
));
144 msg
.msg_id
= AP_IPIMSG_DEC_START
;
145 msg
.vpu_inst_addr
= vpu
->inst_addr
;
147 for (i
= 0; i
< len
; i
++)
148 msg
.data
[i
] = data
[i
];
150 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
151 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
155 int vpu_dec_end(struct vdec_vpu_inst
*vpu
)
157 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_END
);
160 int vpu_dec_deinit(struct vdec_vpu_inst
*vpu
)
162 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_DEINIT
);
165 int vpu_dec_reset(struct vdec_vpu_inst
*vpu
)
167 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_RESET
);