2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: PC Chen <pc.chen@mediatek.com>
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.
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.
15 #include "mtk_vcodec_drv.h"
16 #include "mtk_vcodec_util.h"
17 #include "vdec_ipi_msg.h"
18 #include "vdec_vpu_if.h"
20 static void handle_init_ack_msg(struct vdec_vpu_ipi_init_ack
*msg
)
22 struct vdec_vpu_inst
*vpu
= (struct vdec_vpu_inst
*)
23 (unsigned long)msg
->ap_inst_addr
;
25 mtk_vcodec_debug(vpu
, "+ ap_inst_addr = 0x%llx", msg
->ap_inst_addr
);
27 /* mapping VPU address to kernel virtual address */
28 /* the content in vsi is initialized to 0 in VPU */
29 vpu
->vsi
= vpu_mapping_dm_addr(vpu
->dev
, msg
->vpu_inst_addr
);
30 vpu
->inst_addr
= msg
->vpu_inst_addr
;
32 mtk_vcodec_debug(vpu
, "- vpu_inst_addr = 0x%x", vpu
->inst_addr
);
36 * This function runs in interrupt context and it means there's an IPI MSG
39 void vpu_dec_ipi_handler(void *data
, unsigned int len
, void *priv
)
41 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
)
73 uint32_t msg_id
= *(uint32_t *)msg
;
75 mtk_vcodec_debug(vpu
, "id=%X", msg_id
);
80 err
= vpu_ipi_send(vpu
->dev
, vpu
->id
, msg
, len
);
82 mtk_vcodec_err(vpu
, "send fail vpu_id=%d msg_id=%X status=%d",
83 vpu
->id
, msg_id
, 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
);
115 err
= vpu_ipi_register(vpu
->dev
, vpu
->id
, vpu
->handler
, "vdec", NULL
);
117 mtk_vcodec_err(vpu
, "vpu_ipi_register fail status=%d", err
);
121 memset(&msg
, 0, sizeof(msg
));
122 msg
.msg_id
= AP_IPIMSG_DEC_INIT
;
123 msg
.ap_inst_addr
= (unsigned long)vpu
;
125 mtk_vcodec_debug(vpu
, "vdec_inst=%p", vpu
);
127 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
128 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
132 int vpu_dec_start(struct vdec_vpu_inst
*vpu
, uint32_t *data
, unsigned int len
)
134 struct vdec_ap_ipi_dec_start msg
;
138 mtk_vcodec_debug_enter(vpu
);
140 if (len
> ARRAY_SIZE(msg
.data
)) {
141 mtk_vcodec_err(vpu
, "invalid len = %d\n", len
);
145 memset(&msg
, 0, sizeof(msg
));
146 msg
.msg_id
= AP_IPIMSG_DEC_START
;
147 msg
.vpu_inst_addr
= vpu
->inst_addr
;
149 for (i
= 0; i
< len
; i
++)
150 msg
.data
[i
] = data
[i
];
152 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
153 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
157 int vpu_dec_end(struct vdec_vpu_inst
*vpu
)
159 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_END
);
162 int vpu_dec_deinit(struct vdec_vpu_inst
*vpu
)
164 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_DEINIT
);
167 int vpu_dec_reset(struct vdec_vpu_inst
*vpu
)
169 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_RESET
);