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
)
74 mtk_vcodec_debug(vpu
, "id=%X", *(uint32_t *)msg
);
79 err
= vpu_ipi_send(vpu
->dev
, vpu
->id
, msg
, len
);
81 mtk_vcodec_err(vpu
, "send fail vpu_id=%d msg_id=%X status=%d",
82 vpu
->id
, *(uint32_t *)msg
, err
);
89 static int vcodec_send_ap_ipi(struct vdec_vpu_inst
*vpu
, unsigned int msg_id
)
91 struct vdec_ap_ipi_cmd msg
;
94 mtk_vcodec_debug(vpu
, "+ id=%X", msg_id
);
96 memset(&msg
, 0, sizeof(msg
));
98 msg
.vpu_inst_addr
= vpu
->inst_addr
;
100 err
= vcodec_vpu_send_msg(vpu
, &msg
, sizeof(msg
));
101 mtk_vcodec_debug(vpu
, "- id=%X ret=%d", msg_id
, err
);
105 int vpu_dec_init(struct vdec_vpu_inst
*vpu
)
107 struct vdec_ap_ipi_init msg
;
110 mtk_vcodec_debug_enter(vpu
);
112 init_waitqueue_head(&vpu
->wq
);
114 err
= vpu_ipi_register(vpu
->dev
, vpu
->id
, vpu
->handler
, "vdec", NULL
);
116 mtk_vcodec_err(vpu
, "vpu_ipi_register fail status=%d", err
);
120 memset(&msg
, 0, sizeof(msg
));
121 msg
.msg_id
= AP_IPIMSG_DEC_INIT
;
122 msg
.ap_inst_addr
= (unsigned long)vpu
;
124 mtk_vcodec_debug(vpu
, "vdec_inst=%p", vpu
);
126 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
127 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
131 int vpu_dec_start(struct vdec_vpu_inst
*vpu
, uint32_t *data
, unsigned int len
)
133 struct vdec_ap_ipi_dec_start msg
;
137 mtk_vcodec_debug_enter(vpu
);
139 if (len
> ARRAY_SIZE(msg
.data
)) {
140 mtk_vcodec_err(vpu
, "invalid len = %d\n", len
);
144 memset(&msg
, 0, sizeof(msg
));
145 msg
.msg_id
= AP_IPIMSG_DEC_START
;
146 msg
.vpu_inst_addr
= vpu
->inst_addr
;
148 for (i
= 0; i
< len
; i
++)
149 msg
.data
[i
] = data
[i
];
151 err
= vcodec_vpu_send_msg(vpu
, (void *)&msg
, sizeof(msg
));
152 mtk_vcodec_debug(vpu
, "- ret=%d", err
);
156 int vpu_dec_end(struct vdec_vpu_inst
*vpu
)
158 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_END
);
161 int vpu_dec_deinit(struct vdec_vpu_inst
*vpu
)
163 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_DEINIT
);
166 int vpu_dec_reset(struct vdec_vpu_inst
*vpu
)
168 return vcodec_send_ap_ipi(vpu
, AP_IPIMSG_DEC_RESET
);