1 /*
2 *
3 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 */
16
17 #include "vdec_v4l2_buffer_ops.h"
18 #include <media/v4l2-mem2mem.h>
19 #include <linux/printk.h>
20
vdec_v4l_get_buffer(struct aml_vcodec_ctx * ctx,struct vdec_v4l2_buffer ** out)21 int vdec_v4l_get_buffer(struct aml_vcodec_ctx *ctx,
22 struct vdec_v4l2_buffer **out)
23 {
24 int ret = -1;
25
26 if (ctx->drv_handle == 0)
27 return -EIO;
28
29 ret = ctx->dec_if->get_param(ctx->drv_handle,
30 GET_PARAM_FREE_FRAME_BUFFER, out);
31
32 return ret;
33 }
34 EXPORT_SYMBOL(vdec_v4l_get_buffer);
35
vdec_v4l_get_pic_info(struct aml_vcodec_ctx * ctx,struct vdec_pic_info * pic)36 int vdec_v4l_get_pic_info(struct aml_vcodec_ctx *ctx,
37 struct vdec_pic_info *pic)
38 {
39 int ret = 0;
40
41 if (ctx->drv_handle == 0)
42 return -EIO;
43
44 ret = ctx->dec_if->get_param(ctx->drv_handle,
45 GET_PARAM_PIC_INFO, pic);
46
47 return ret;
48 }
49 EXPORT_SYMBOL(vdec_v4l_get_pic_info);
50
vdec_v4l_set_ps_infos(struct aml_vcodec_ctx * ctx,struct aml_vdec_ps_infos * ps)51 int vdec_v4l_set_ps_infos(struct aml_vcodec_ctx *ctx,
52 struct aml_vdec_ps_infos *ps)
53 {
54 int ret = 0;
55
56 if (ctx->drv_handle == 0)
57 return -EIO;
58
59 ret = ctx->dec_if->set_param(ctx->drv_handle,
60 SET_PARAM_PS_INFO, ps);
61
62 return ret;
63 }
64 EXPORT_SYMBOL(vdec_v4l_set_ps_infos);
65
vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx * ctx,struct aml_vdec_hdr_infos * hdr)66 int vdec_v4l_set_hdr_infos(struct aml_vcodec_ctx *ctx,
67 struct aml_vdec_hdr_infos *hdr)
68 {
69 int ret = 0;
70
71 if (ctx->drv_handle == 0)
72 return -EIO;
73
74 ret = ctx->dec_if->set_param(ctx->drv_handle,
75 SET_PARAM_HDR_INFO, hdr);
76
77 return ret;
78 }
79 EXPORT_SYMBOL(vdec_v4l_set_hdr_infos);
80
aml_wait_dpb_ready(struct aml_vcodec_ctx * ctx)81 static void aml_wait_dpb_ready(struct aml_vcodec_ctx *ctx)
82 {
83 ulong expires;
84
85 expires = jiffies + msecs_to_jiffies(1000);
86 while (!ctx->v4l_codec_dpb_ready) {
87 u32 ready_num = 0;
88
89 if (time_after(jiffies, expires)) {
90 pr_err("the DPB state has not ready.\n");
91 break;
92 }
93
94 ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx);
95 if ((ready_num + ctx->buf_used_count) >= ctx->dpb_size)
96 ctx->v4l_codec_dpb_ready = true;
97 }
98 }
99
aml_vdec_pic_info_update(struct aml_vcodec_ctx * ctx)100 void aml_vdec_pic_info_update(struct aml_vcodec_ctx *ctx)
101 {
102 unsigned int dpbsize = 0;
103 int ret;
104
105 if (ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_PIC_INFO, &ctx->last_decoded_picinfo)) {
106 pr_err("Cannot get param : GET_PARAM_PICTURE_INFO ERR\n");
107 return;
108 }
109
110 if (ctx->last_decoded_picinfo.visible_width == 0 ||
111 ctx->last_decoded_picinfo.visible_height == 0 ||
112 ctx->last_decoded_picinfo.coded_width == 0 ||
113 ctx->last_decoded_picinfo.coded_height == 0) {
114 pr_err("Cannot get correct pic info\n");
115 return;
116 }
117
118 ret = ctx->dec_if->get_param(ctx->drv_handle, GET_PARAM_DPB_SIZE, &dpbsize);
119 if (dpbsize == 0)
120 pr_err("Incorrect dpb size, ret=%d\n", ret);
121
122 /* update picture information */
123 ctx->dpb_size = dpbsize;
124 ctx->picinfo = ctx->last_decoded_picinfo;
125 }
126
vdec_v4l_post_evet(struct aml_vcodec_ctx * ctx,u32 event)127 int vdec_v4l_post_evet(struct aml_vcodec_ctx *ctx, u32 event)
128 {
129 int ret = 0;
130
131 if (ctx->drv_handle == 0)
132 return -EIO;
133 if (event == 1)
134 ctx->reset_flag = 2;
135 ret = ctx->dec_if->set_param(ctx->drv_handle,
136 SET_PARAM_POST_EVENT, &event);
137
138 return ret;
139 }
140 EXPORT_SYMBOL(vdec_v4l_post_evet);
141
vdec_v4l_res_ch_event(struct aml_vcodec_ctx * ctx)142 int vdec_v4l_res_ch_event(struct aml_vcodec_ctx *ctx)
143 {
144 int ret = 0;
145 struct aml_vcodec_dev *dev = ctx->dev;
146
147 if (ctx->drv_handle == 0)
148 return -EIO;
149
150 /* wait the DPB state to be ready. */
151 aml_wait_dpb_ready(ctx);
152
153 aml_vdec_pic_info_update(ctx);
154
155 mutex_lock(&ctx->state_lock);
156
157 ctx->state = AML_STATE_FLUSHING;/*prepare flushing*/
158
159 pr_info("[%d]: vcodec state (AML_STATE_FLUSHING-RESCHG)\n", ctx->id);
160
161 mutex_unlock(&ctx->state_lock);
162
163 ctx->q_data[AML_Q_DATA_SRC].resolution_changed = true;
164 v4l2_m2m_suspend(dev->m2m_dev_dec);
165
166 return ret;
167 }
168 EXPORT_SYMBOL(vdec_v4l_res_ch_event);
169
170
vdec_v4l_write_frame_sync(struct aml_vcodec_ctx * ctx)171 int vdec_v4l_write_frame_sync(struct aml_vcodec_ctx *ctx)
172 {
173 int ret = 0;
174
175 if (ctx->drv_handle == 0)
176 return -EIO;
177
178 ret = ctx->dec_if->set_param(ctx->drv_handle,
179 SET_PARAM_WRITE_FRAME_SYNC, NULL);
180
181 return ret;
182 }
183 EXPORT_SYMBOL(vdec_v4l_write_frame_sync);
184
185