blob: 671d9d0c63b83d4504cdfdb6c2cbdb1b4d074400 [file] [log] [blame]
Googler9398cc32022-12-02 17:21:52 +08001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
Googler4f18c0c2022-09-20 17:23:36 +08002/*
Googler9398cc32022-12-02 17:21:52 +08003 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
Googler4f18c0c2022-09-20 17:23:36 +08004 */
5
6/* Linux Headers */
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/spinlock.h>
10#include <linux/irqreturn.h>
11#include <linux/errno.h>
12#include <linux/irq.h>
13#include <linux/slab.h>
14#include <linux/interrupt.h>
15#include <linux/fdtable.h>
16#include <linux/file.h>
17#include <linux/list.h>
18#include <linux/kthread.h>
19#include <linux/ktime.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22#include <linux/sysfs.h>
23#include <linux/uaccess.h>
Googler9398cc32022-12-02 17:21:52 +080024#include <uapi/linux/sched/types.h>
Googler9726be62022-12-14 05:53:31 +000025#include <asm/div64.h>
Googler9398cc32022-12-02 17:21:52 +080026/* media module used media/registers/cpu_version.h since kernel 5.4 */
27#include <linux/amlogic/media/registers/cpu_version.h>
28
Googler4f18c0c2022-09-20 17:23:36 +080029/* Android Headers */
30
31/* Amlogic Headers */
32#include <linux/amlogic/media/vout/vinfo.h>
33#include <linux/amlogic/media/vout/vout_notify.h>
34#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
35#include <linux/amlogic/media/canvas/canvas.h>
36#include <linux/amlogic/media/canvas/canvas_mgr.h>
37#endif
38#ifdef CONFIG_AMLOGIC_VPU
39#include <linux/amlogic/media/vpu/vpu.h>
40#endif
41#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
42#include <linux/amlogic/media/amvecm/ve.h>
43#endif
44
45#ifdef CONFIG_AMLOGIC_MEDIA_VIDEO
Googler4f18c0c2022-09-20 17:23:36 +080046#include <linux/amlogic/media/video_sink/video.h>
47#endif
48#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
49#include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
50#endif
Googler9726be62022-12-14 05:53:31 +000051#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
52#include <linux/amlogic/media/vpu_secure/vpu_secure.h>
53#endif
Googler4f18c0c2022-09-20 17:23:36 +080054/* Local Headers */
55#include "osd_canvas.h"
56#include "osd_prot.h"
57#include "osd_antiflicker.h"
58#include "osd_clone.h"
59#include "osd_log.h"
60#include "osd_reg.h"
61#include "osd_io.h"
62#include "osd_backup.h"
63
64#include "osd_hw.h"
65#include "osd_hw_def.h"
66#include "osd_fb.h"
Googler9726be62022-12-14 05:53:31 +000067#include "osd_sw_sync.h"
Googler4f18c0c2022-09-20 17:23:36 +080068
69#ifdef CONFIG_AMLOGIC_VSYNC_FIQ_ENABLE
70#define FIQ_VSYNC
71#endif
72#define VOUT_ENCI 1
73#define VOUT_ENCP 2
74#define VOUT_ENCT 3
75#define OSD_TYPE_TOP_FIELD 0
76#define OSD_TYPE_BOT_FIELD 1
77
78#define OSD_DISP_DEBUG 1
79#define OSD_OLD_HWC (0x01 << 0)
80#define OSD_OTHER_NEW_HWC (0x01 << 1)
81#define OSD_G12A_NEW_HWC (0x01 << 2)
82
83#define WAIT_AFBC_READY_COUNT 100
84#define NEW_PPS_PHASE
85
86#define osd_tprintk(...)
87
88#define FREE_SCALE_MAX_WIDTH 1920
Googler9726be62022-12-14 05:53:31 +000089#define WAIT_CNT_MAX 20
90
Googler4f18c0c2022-09-20 17:23:36 +080091struct hw_para_s osd_hw;
Googler9398cc32022-12-02 17:21:52 +080092struct osd_device_hw_s osd_dev_hw;
93
Googler4f18c0c2022-09-20 17:23:36 +080094static DEFINE_MUTEX(osd_mutex);
95static DECLARE_WAIT_QUEUE_HEAD(osd_vsync_wq);
Googler9726be62022-12-14 05:53:31 +000096static DECLARE_WAIT_QUEUE_HEAD(osd_vsync2_wq);
Googler9398cc32022-12-02 17:21:52 +080097static DECLARE_WAIT_QUEUE_HEAD(osd_vsync3_wq);
98
99static DECLARE_WAIT_QUEUE_HEAD(osd_rdma_vpp0_done_wq);
100static DECLARE_WAIT_QUEUE_HEAD(osd_rdma_vpp1_done_wq);
101static DECLARE_WAIT_QUEUE_HEAD(osd_rdma_vpp2_done_wq);
Googler4f18c0c2022-09-20 17:23:36 +0800102
Googler9726be62022-12-14 05:53:31 +0000103static bool vsync_hit[VIU_COUNT];
Googler4f18c0c2022-09-20 17:23:36 +0800104static bool osd_update_window_axis;
105static int osd_afbc_dec_enable;
106static int ext_canvas_id[HW_OSD_COUNT];
107static int osd_extra_idx[HW_OSD_COUNT][2];
108static bool suspend_flag;
Googler9726be62022-12-14 05:53:31 +0000109static int osd_log_out;
Googler4f18c0c2022-09-20 17:23:36 +0800110static u32 rdma_dt_cnt;
Googler9726be62022-12-14 05:53:31 +0000111static bool update_to_dv;
Googler4f18c0c2022-09-20 17:23:36 +0800112static void osd_clone_pan(u32 index, u32 yoffset, int debug_flag);
113static void osd_set_dummy_data(u32 index, u32 alpha);
Googler9398cc32022-12-02 17:21:52 +0800114static void osd_wait_vsync_hw_viux(u32 output_index);
Googler9726be62022-12-14 05:53:31 +0000115static void osd_setting_default_hwc(void);
Googler4f18c0c2022-09-20 17:23:36 +0800116
117struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT];
118
119struct hw_osd_reg_s hw_osd_reg_array_g12a[HW_OSD_COUNT] = {
120 {
121 VIU_OSD1_CTRL_STAT,
122 VIU_OSD1_CTRL_STAT2,
123 VIU_OSD1_COLOR_ADDR,
124 VIU_OSD1_COLOR,
125 VIU_OSD1_TCOLOR_AG0,
126 VIU_OSD1_TCOLOR_AG1,
127 VIU_OSD1_TCOLOR_AG2,
128 VIU_OSD1_TCOLOR_AG3,
129 VIU_OSD1_BLK0_CFG_W0,
130 VIU_OSD1_BLK0_CFG_W1,
131 VIU_OSD1_BLK0_CFG_W2,
132 VIU_OSD1_BLK0_CFG_W3,
133 VIU_OSD1_BLK0_CFG_W4,
134 VIU_OSD1_BLK1_CFG_W4,
135 VIU_OSD1_BLK2_CFG_W4,
136 VIU_OSD1_FIFO_CTRL_STAT,
137 VIU_OSD1_TEST_RDDATA,
138 VIU_OSD1_PROT_CTRL,
139 VIU_OSD1_MALI_UNPACK_CTRL,
140 VIU_OSD1_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000141 VPP_WRAP_OSD1_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800142
143 VPP_OSD_SCALE_COEF_IDX,
144 VPP_OSD_SCALE_COEF,
145 VPP_OSD_VSC_PHASE_STEP,
146 VPP_OSD_VSC_INI_PHASE,
147 VPP_OSD_VSC_CTRL0,
148 VPP_OSD_HSC_PHASE_STEP,
149 VPP_OSD_HSC_INI_PHASE,
150 VPP_OSD_HSC_CTRL0,
151 VPP_OSD_SC_DUMMY_DATA,
152 VPP_OSD_SC_CTRL0,
153 VPP_OSD_SCI_WH_M1,
154 VPP_OSD_SCO_H_START_END,
155 VPP_OSD_SCO_V_START_END,
Googler9398cc32022-12-02 17:21:52 +0800156 OSD_DB_FLT_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800157 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0,
158 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0,
159 VPU_MAFBC_FORMAT_SPECIFIER_S0,
160 VPU_MAFBC_BUFFER_WIDTH_S0,
161 VPU_MAFBC_BUFFER_HEIGHT_S0,
162 VPU_MAFBC_BOUNDING_BOX_X_START_S0,
163 VPU_MAFBC_BOUNDING_BOX_X_END_S0,
164 VPU_MAFBC_BOUNDING_BOX_Y_START_S0,
165 VPU_MAFBC_BOUNDING_BOX_Y_END_S0,
166 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0,
167 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0,
168 VPU_MAFBC_OUTPUT_BUF_STRIDE_S0,
169 VPU_MAFBC_PREFETCH_CFG_S0,
Googler9398cc32022-12-02 17:21:52 +0800170
171 MALI_AFBCD_TOP_CTRL,
172 VPU_MAFBC_IRQ_MASK,
173 VPU_MAFBC_SURFACE_CFG,
174 VPU_MAFBC_COMMAND,
175 VPU_MAFBC_IRQ_RAW_STATUS,
176 VPU_MAFBC_IRQ_CLEAR,
177
178 VIU2_OSD1_UNSUPPORT,
Googler4f18c0c2022-09-20 17:23:36 +0800179 },
180 {
181 VIU_OSD2_CTRL_STAT,
182 VIU_OSD2_CTRL_STAT2,
183 VIU_OSD2_COLOR_ADDR,
184 VIU_OSD2_COLOR,
185 VIU_OSD2_TCOLOR_AG0,
186 VIU_OSD2_TCOLOR_AG1,
187 VIU_OSD2_TCOLOR_AG2,
188 VIU_OSD2_TCOLOR_AG3,
189 VIU_OSD2_BLK0_CFG_W0,
190 VIU_OSD2_BLK0_CFG_W1,
191 VIU_OSD2_BLK0_CFG_W2,
192 VIU_OSD2_BLK0_CFG_W3,
193 VIU_OSD2_BLK0_CFG_W4,
194 VIU_OSD2_BLK1_CFG_W4,
195 VIU_OSD2_BLK2_CFG_W4,
196 VIU_OSD2_FIFO_CTRL_STAT,
197 VIU_OSD2_TEST_RDDATA,
198 VIU_OSD2_PROT_CTRL,
199 VIU_OSD2_MALI_UNPACK_CTRL,
200 VIU_OSD2_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000201 VPP_WRAP_OSD2_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800202
203 OSD2_SCALE_COEF_IDX,
204 OSD2_SCALE_COEF,
205 OSD2_VSC_PHASE_STEP,
206 OSD2_VSC_INI_PHASE,
207 OSD2_VSC_CTRL0,
208 OSD2_HSC_PHASE_STEP,
209 OSD2_HSC_INI_PHASE,
210 OSD2_HSC_CTRL0,
211 OSD2_SC_DUMMY_DATA,
212 OSD2_SC_CTRL0,
213 OSD2_SCI_WH_M1,
214 OSD2_SCO_H_START_END,
215 OSD2_SCO_V_START_END,
Googler9398cc32022-12-02 17:21:52 +0800216 OSD2_DB_FLT_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800217 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1,
218 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1,
219 VPU_MAFBC_FORMAT_SPECIFIER_S1,
220 VPU_MAFBC_BUFFER_WIDTH_S1,
221 VPU_MAFBC_BUFFER_HEIGHT_S1,
222 VPU_MAFBC_BOUNDING_BOX_X_START_S1,
223 VPU_MAFBC_BOUNDING_BOX_X_END_S1,
224 VPU_MAFBC_BOUNDING_BOX_Y_START_S1,
225 VPU_MAFBC_BOUNDING_BOX_Y_END_S1,
226 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1,
227 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1,
228 VPU_MAFBC_OUTPUT_BUF_STRIDE_S1,
229 VPU_MAFBC_PREFETCH_CFG_S1,
Googler9398cc32022-12-02 17:21:52 +0800230
231 MALI_AFBCD_TOP_CTRL,
232 VPU_MAFBC_IRQ_MASK,
233 VPU_MAFBC_SURFACE_CFG,
234 VPU_MAFBC_COMMAND,
235 VPU_MAFBC_IRQ_RAW_STATUS,
236 VPU_MAFBC_IRQ_CLEAR,
237
238 VIU2_OSD1_UNSUPPORT,
Googler4f18c0c2022-09-20 17:23:36 +0800239 },
240 {
241 VIU_OSD3_CTRL_STAT,
242 VIU_OSD3_CTRL_STAT2,
243 VIU_OSD3_COLOR_ADDR,
244 VIU_OSD3_COLOR,
245 VIU_OSD3_TCOLOR_AG0,
246 VIU_OSD3_TCOLOR_AG1,
247 VIU_OSD3_TCOLOR_AG2,
248 VIU_OSD3_TCOLOR_AG3,
249 VIU_OSD3_BLK0_CFG_W0,
250 VIU_OSD3_BLK0_CFG_W1,
251 VIU_OSD3_BLK0_CFG_W2,
252 VIU_OSD3_BLK0_CFG_W3,
253 VIU_OSD3_BLK0_CFG_W4,
254 VIU_OSD3_BLK1_CFG_W4,
255 VIU_OSD3_BLK2_CFG_W4,
256 VIU_OSD3_FIFO_CTRL_STAT,
257 VIU_OSD3_TEST_RDDATA,
258 VIU_OSD3_PROT_CTRL,
259 VIU_OSD3_MALI_UNPACK_CTRL,
260 VIU_OSD3_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000261 VPP_WRAP_OSD3_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800262
263 OSD34_SCALE_COEF_IDX,
264 OSD34_SCALE_COEF,
265 OSD34_VSC_PHASE_STEP,
266 OSD34_VSC_INI_PHASE,
267 OSD34_VSC_CTRL0,
268 OSD34_HSC_PHASE_STEP,
269 OSD34_HSC_INI_PHASE,
270 OSD34_HSC_CTRL0,
271 OSD34_SC_DUMMY_DATA,
272 OSD34_SC_CTRL0,
273 OSD34_SCI_WH_M1,
274 OSD34_SCO_H_START_END,
275 OSD34_SCO_V_START_END,
Googler9398cc32022-12-02 17:21:52 +0800276 OSD34_DB_FLT_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800277 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S2,
278 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S2,
279 VPU_MAFBC_FORMAT_SPECIFIER_S2,
280 VPU_MAFBC_BUFFER_WIDTH_S2,
281 VPU_MAFBC_BUFFER_HEIGHT_S2,
282 VPU_MAFBC_BOUNDING_BOX_X_START_S2,
283 VPU_MAFBC_BOUNDING_BOX_X_END_S2,
284 VPU_MAFBC_BOUNDING_BOX_Y_START_S2,
285 VPU_MAFBC_BOUNDING_BOX_Y_END_S2,
286 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S2,
287 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S2,
288 VPU_MAFBC_OUTPUT_BUF_STRIDE_S2,
289 VPU_MAFBC_PREFETCH_CFG_S2,
Googler9398cc32022-12-02 17:21:52 +0800290
291 MALI_AFBCD_TOP_CTRL,
292 VPU_MAFBC_IRQ_MASK,
293 VPU_MAFBC_SURFACE_CFG,
294 VPU_MAFBC_COMMAND,
295 VPU_MAFBC_IRQ_RAW_STATUS,
296 VPU_MAFBC_IRQ_CLEAR,
Googler4f18c0c2022-09-20 17:23:36 +0800297 },
298 {
299 VIU2_OSD1_CTRL_STAT,
300 VIU2_OSD1_CTRL_STAT2,
301 VIU2_OSD1_COLOR_ADDR,
302 VIU2_OSD1_COLOR,
303 VIU2_OSD1_TCOLOR_AG0,
304 VIU2_OSD1_TCOLOR_AG1,
305 VIU2_OSD1_TCOLOR_AG2,
306 VIU2_OSD1_TCOLOR_AG3,
307 VIU2_OSD1_BLK0_CFG_W0,
308 VIU2_OSD1_BLK0_CFG_W1,
309 VIU2_OSD1_BLK0_CFG_W2,
310 VIU2_OSD1_BLK0_CFG_W3,
311 VIU2_OSD1_BLK0_CFG_W4,
312 VIU2_OSD1_BLK1_CFG_W4,
313 VIU2_OSD1_BLK2_CFG_W4,
314 VIU2_OSD1_FIFO_CTRL_STAT,
315 VIU2_OSD1_TEST_RDDATA,
316 VIU2_OSD1_PROT_CTRL,
317 VIU2_OSD1_MALI_UNPACK_CTRL,
318 VIU2_OSD1_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000319 VIU2_OSD1_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800320
321 VIU2_OSD1_UNSUPPORT,
322 VIU2_OSD1_UNSUPPORT,
323 VIU2_OSD1_UNSUPPORT,
324 VIU2_OSD1_UNSUPPORT,
325 VIU2_OSD1_UNSUPPORT,
326 VIU2_OSD1_UNSUPPORT,
327 VIU2_OSD1_UNSUPPORT,
328 VIU2_OSD1_UNSUPPORT,
329 VIU2_OSD1_UNSUPPORT,
330 VIU2_OSD1_UNSUPPORT,
331 VIU2_OSD1_UNSUPPORT,
332 VIU2_OSD1_UNSUPPORT,
333 VIU2_OSD1_UNSUPPORT,
334 VIU2_OSD1_UNSUPPORT,
335 VIU2_OSD1_UNSUPPORT,
336 VIU2_OSD1_UNSUPPORT,
337 VIU2_OSD1_UNSUPPORT,
338 VIU2_OSD1_UNSUPPORT,
339 VIU2_OSD1_UNSUPPORT,
340 VIU2_OSD1_UNSUPPORT,
341 VIU2_OSD1_UNSUPPORT,
342 VIU2_OSD1_UNSUPPORT,
343 VIU2_OSD1_UNSUPPORT,
344 VIU2_OSD1_UNSUPPORT,
345 VIU2_OSD1_UNSUPPORT,
346 VIU2_OSD1_UNSUPPORT,
Googler9398cc32022-12-02 17:21:52 +0800347
348 VIU2_OSD1_UNSUPPORT,
349 VIU2_OSD1_UNSUPPORT,
350 VIU2_OSD1_UNSUPPORT,
351 VIU2_OSD1_UNSUPPORT,
352 VIU2_OSD1_UNSUPPORT,
353 VIU2_OSD1_UNSUPPORT,
354 VIU2_OSD1_UNSUPPORT,
Googler4f18c0c2022-09-20 17:23:36 +0800355 }
356};
357
358struct hw_osd_reg_s hw_osd_reg_array_tl1[HW_OSD_COUNT] = {
359 {
360 VIU_OSD1_CTRL_STAT,
361 VIU_OSD1_CTRL_STAT2,
362 VIU_OSD1_COLOR_ADDR,
363 VIU_OSD1_COLOR,
364 VIU_OSD1_TCOLOR_AG0,
365 VIU_OSD1_TCOLOR_AG1,
366 VIU_OSD1_TCOLOR_AG2,
367 VIU_OSD1_TCOLOR_AG3,
368 VIU_OSD1_BLK0_CFG_W0,
369 VIU_OSD1_BLK0_CFG_W1,
370 VIU_OSD1_BLK0_CFG_W2,
371 VIU_OSD1_BLK0_CFG_W3,
372 VIU_OSD1_BLK0_CFG_W4,
373 VIU_OSD1_BLK1_CFG_W4,
374 VIU_OSD1_BLK2_CFG_W4,
375 VIU_OSD1_FIFO_CTRL_STAT,
376 VIU_OSD1_TEST_RDDATA,
377 VIU_OSD1_PROT_CTRL,
378 VIU_OSD1_MALI_UNPACK_CTRL,
379 VIU_OSD1_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000380 VPP_WRAP_OSD1_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800381
382 VPP_OSD_SCALE_COEF_IDX,
383 VPP_OSD_SCALE_COEF,
384 VPP_OSD_VSC_PHASE_STEP,
385 VPP_OSD_VSC_INI_PHASE,
386 VPP_OSD_VSC_CTRL0,
387 VPP_OSD_HSC_PHASE_STEP,
388 VPP_OSD_HSC_INI_PHASE,
389 VPP_OSD_HSC_CTRL0,
390 VPP_OSD_SC_DUMMY_DATA,
391 VPP_OSD_SC_CTRL0,
392 VPP_OSD_SCI_WH_M1,
393 VPP_OSD_SCO_H_START_END,
394 VPP_OSD_SCO_V_START_END,
Googler9398cc32022-12-02 17:21:52 +0800395 OSD_DB_FLT_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800396 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0,
397 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0,
398 VPU_MAFBC_FORMAT_SPECIFIER_S0,
399 VPU_MAFBC_BUFFER_WIDTH_S0,
400 VPU_MAFBC_BUFFER_HEIGHT_S0,
401 VPU_MAFBC_BOUNDING_BOX_X_START_S0,
402 VPU_MAFBC_BOUNDING_BOX_X_END_S0,
403 VPU_MAFBC_BOUNDING_BOX_Y_START_S0,
404 VPU_MAFBC_BOUNDING_BOX_Y_END_S0,
405 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0,
406 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0,
407 VPU_MAFBC_OUTPUT_BUF_STRIDE_S0,
408 VPU_MAFBC_PREFETCH_CFG_S0,
Googler9398cc32022-12-02 17:21:52 +0800409
410 MALI_AFBCD_TOP_CTRL,
411 VPU_MAFBC_IRQ_MASK,
412 VPU_MAFBC_SURFACE_CFG,
413 VPU_MAFBC_COMMAND,
414 VPU_MAFBC_IRQ_RAW_STATUS,
415 VPU_MAFBC_IRQ_CLEAR,
416
417 VIU2_OSD1_UNSUPPORT,
Googler4f18c0c2022-09-20 17:23:36 +0800418 },
419 {
420 VIU_OSD2_CTRL_STAT,
421 VIU_OSD2_CTRL_STAT2,
422 VIU_OSD2_COLOR_ADDR,
423 VIU_OSD2_COLOR,
424 VIU_OSD2_TCOLOR_AG0,
425 VIU_OSD2_TCOLOR_AG1,
426 VIU_OSD2_TCOLOR_AG2,
427 VIU_OSD2_TCOLOR_AG3,
428 VIU_OSD2_BLK0_CFG_W0,
429 VIU_OSD2_BLK0_CFG_W1,
430 VIU_OSD2_BLK0_CFG_W2,
431 VIU_OSD2_BLK0_CFG_W3,
432 VIU_OSD2_BLK0_CFG_W4,
433 VIU_OSD2_BLK1_CFG_W4,
434 VIU_OSD2_BLK2_CFG_W4,
435 VIU_OSD2_FIFO_CTRL_STAT,
436 VIU_OSD2_TEST_RDDATA,
437 VIU_OSD2_PROT_CTRL,
438 VIU_OSD2_MALI_UNPACK_CTRL,
439 VIU_OSD2_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000440 VPP_WRAP_OSD2_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800441
442 OSD2_SCALE_COEF_IDX,
443 OSD2_SCALE_COEF,
444 OSD2_VSC_PHASE_STEP,
445 OSD2_VSC_INI_PHASE,
446 OSD2_VSC_CTRL0,
447 OSD2_HSC_PHASE_STEP,
448 OSD2_HSC_INI_PHASE,
449 OSD2_HSC_CTRL0,
450 OSD2_SC_DUMMY_DATA,
451 OSD2_SC_CTRL0,
452 OSD2_SCI_WH_M1,
453 OSD2_SCO_H_START_END,
454 OSD2_SCO_V_START_END,
Googler9398cc32022-12-02 17:21:52 +0800455 OSD2_DB_FLT_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800456 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1,
457 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1,
458 VPU_MAFBC_FORMAT_SPECIFIER_S1,
459 VPU_MAFBC_BUFFER_WIDTH_S1,
460 VPU_MAFBC_BUFFER_HEIGHT_S1,
461 VPU_MAFBC_BOUNDING_BOX_X_START_S1,
462 VPU_MAFBC_BOUNDING_BOX_X_END_S1,
463 VPU_MAFBC_BOUNDING_BOX_Y_START_S1,
464 VPU_MAFBC_BOUNDING_BOX_Y_END_S1,
465 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1,
466 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1,
467 VPU_MAFBC_OUTPUT_BUF_STRIDE_S1,
468 VPU_MAFBC_PREFETCH_CFG_S1,
Googler9398cc32022-12-02 17:21:52 +0800469
470 MALI_AFBCD_TOP_CTRL,
471 VPU_MAFBC_IRQ_MASK,
472 VPU_MAFBC_SURFACE_CFG,
473 VPU_MAFBC_COMMAND,
474 VPU_MAFBC_IRQ_RAW_STATUS,
475 VPU_MAFBC_IRQ_CLEAR,
476
477 VIU2_OSD1_UNSUPPORT,
Googler4f18c0c2022-09-20 17:23:36 +0800478 },
479 {
480 VIU2_OSD1_CTRL_STAT,
481 VIU2_OSD1_CTRL_STAT2,
482 VIU2_OSD1_COLOR_ADDR,
483 VIU2_OSD1_COLOR,
484 VIU2_OSD1_TCOLOR_AG0,
485 VIU2_OSD1_TCOLOR_AG1,
486 VIU2_OSD1_TCOLOR_AG2,
487 VIU2_OSD1_TCOLOR_AG3,
488 VIU2_OSD1_BLK0_CFG_W0,
489 VIU2_OSD1_BLK0_CFG_W1,
490 VIU2_OSD1_BLK0_CFG_W2,
491 VIU2_OSD1_BLK0_CFG_W3,
492 VIU2_OSD1_BLK0_CFG_W4,
493 VIU2_OSD1_BLK1_CFG_W4,
494 VIU2_OSD1_BLK2_CFG_W4,
495 VIU2_OSD1_FIFO_CTRL_STAT,
496 VIU2_OSD1_TEST_RDDATA,
497 VIU2_OSD1_PROT_CTRL,
498 VIU2_OSD1_MALI_UNPACK_CTRL,
499 VIU2_OSD1_DIMM_CTRL,
Googler9726be62022-12-14 05:53:31 +0000500 VIU2_OSD1_MATRIX_EN_CTRL,
Googler4f18c0c2022-09-20 17:23:36 +0800501
502 VIU2_OSD1_UNSUPPORT,
503 VIU2_OSD1_UNSUPPORT,
504 VIU2_OSD1_UNSUPPORT,
505 VIU2_OSD1_UNSUPPORT,
506 VIU2_OSD1_UNSUPPORT,
507 VIU2_OSD1_UNSUPPORT,
508 VIU2_OSD1_UNSUPPORT,
509 VIU2_OSD1_UNSUPPORT,
510 VIU2_OSD1_UNSUPPORT,
511 VIU2_OSD1_UNSUPPORT,
512 VIU2_OSD1_UNSUPPORT,
513 VIU2_OSD1_UNSUPPORT,
514 VIU2_OSD1_UNSUPPORT,
515 VIU2_OSD1_UNSUPPORT,
516 VIU2_OSD1_UNSUPPORT,
517 VIU2_OSD1_UNSUPPORT,
518 VIU2_OSD1_UNSUPPORT,
519 VIU2_OSD1_UNSUPPORT,
520 VIU2_OSD1_UNSUPPORT,
521 VIU2_OSD1_UNSUPPORT,
522 VIU2_OSD1_UNSUPPORT,
523 VIU2_OSD1_UNSUPPORT,
524 VIU2_OSD1_UNSUPPORT,
525 VIU2_OSD1_UNSUPPORT,
526 VIU2_OSD1_UNSUPPORT,
527 VIU2_OSD1_UNSUPPORT,
Googler9398cc32022-12-02 17:21:52 +0800528 VIU2_OSD1_UNSUPPORT,
529
530 VIU2_OSD1_UNSUPPORT,
531 VIU2_OSD1_UNSUPPORT,
532 VIU2_OSD1_UNSUPPORT,
533 VIU2_OSD1_UNSUPPORT,
534 VIU2_OSD1_UNSUPPORT,
535 VIU2_OSD1_UNSUPPORT,
536 VIU2_OSD1_UNSUPPORT,
Googler4f18c0c2022-09-20 17:23:36 +0800537 }
538};
539
Googler9398cc32022-12-02 17:21:52 +0800540struct hw_osd_reg_s hw_osd_reg_array_t7[HW_OSD_COUNT] = {
541 {
542 VIU_OSD1_CTRL_STAT,
543 VIU_OSD1_CTRL_STAT2,
544 VIU_OSD1_COLOR_ADDR,
545 VIU_OSD1_COLOR,
546 VIU_OSD1_TCOLOR_AG0,
547 VIU_OSD1_TCOLOR_AG1,
548 VIU_OSD1_TCOLOR_AG2,
549 VIU_OSD1_TCOLOR_AG3,
550 VIU_OSD1_BLK0_CFG_W0,
551 VIU_OSD1_BLK0_CFG_W1,
552 VIU_OSD1_BLK0_CFG_W2,
553 VIU_OSD1_BLK0_CFG_W3,
554 VIU_OSD1_BLK0_CFG_W4,
555 VIU_OSD1_BLK1_CFG_W4,
556 VIU_OSD1_BLK2_CFG_W4,
557 VIU_OSD1_FIFO_CTRL_STAT,
558 VIU_OSD1_TEST_RDDATA,
559 VIU_OSD1_PROT_CTRL,
560 VIU_OSD1_MALI_UNPACK_CTRL,
561 VIU_OSD1_DIMM_CTRL,
562 VPP_WRAP_OSD1_MATRIX_EN_CTRL,
563
564 T7_VPP_OSD_SCALE_COEF_IDX,
565 T7_VPP_OSD_SCALE_COEF,
566 T7_VPP_OSD_VSC_PHASE_STEP,
567 T7_VPP_OSD_VSC_INI_PHASE,
568 T7_VPP_OSD_VSC_CTRL0,
569 T7_VPP_OSD_HSC_PHASE_STEP,
570 T7_VPP_OSD_HSC_INI_PHASE,
571 T7_VPP_OSD_HSC_CTRL0,
572 T7_VPP_OSD_SC_DUMMY_DATA,
573 T7_VPP_OSD_SC_CTRL0,
574 T7_VPP_OSD_SCI_WH_M1,
575 T7_VPP_OSD_SCO_H_START_END,
576 T7_VPP_OSD_SCO_V_START_END,
577 OSD_DB_FLT_CTRL,
578 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0,
579 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0,
580 VPU_MAFBC_FORMAT_SPECIFIER_S0,
581 VPU_MAFBC_BUFFER_WIDTH_S0,
582 VPU_MAFBC_BUFFER_HEIGHT_S0,
583 VPU_MAFBC_BOUNDING_BOX_X_START_S0,
584 VPU_MAFBC_BOUNDING_BOX_X_END_S0,
585 VPU_MAFBC_BOUNDING_BOX_Y_START_S0,
586 VPU_MAFBC_BOUNDING_BOX_Y_END_S0,
587 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0,
588 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0,
589 VPU_MAFBC_OUTPUT_BUF_STRIDE_S0,
590 VPU_MAFBC_PREFETCH_CFG_S0,
591
592 MALI_AFBCD_TOP_CTRL,
593 VPU_MAFBC_IRQ_MASK,
594 VPU_MAFBC_SURFACE_CFG,
595 VPU_MAFBC_COMMAND,
596 VPU_MAFBC_IRQ_RAW_STATUS,
597 VPU_MAFBC_IRQ_CLEAR,
598
599 VPP_OSD1_SCALE_CTRL,
600 },
601 {
602 VIU_OSD2_CTRL_STAT,
603 VIU_OSD2_CTRL_STAT2,
604 VIU_OSD2_COLOR_ADDR,
605 VIU_OSD2_COLOR,
606 VIU_OSD2_TCOLOR_AG0,
607 VIU_OSD2_TCOLOR_AG1,
608 VIU_OSD2_TCOLOR_AG2,
609 VIU_OSD2_TCOLOR_AG3,
610 VIU_OSD2_BLK0_CFG_W0,
611 VIU_OSD2_BLK0_CFG_W1,
612 VIU_OSD2_BLK0_CFG_W2,
613 VIU_OSD2_BLK0_CFG_W3,
614 VIU_OSD2_BLK0_CFG_W4,
615 VIU_OSD2_BLK1_CFG_W4,
616 VIU_OSD2_BLK2_CFG_W4,
617 VIU_OSD2_FIFO_CTRL_STAT,
618 VIU_OSD2_TEST_RDDATA,
619 VIU_OSD2_PROT_CTRL,
620 VIU_OSD2_MALI_UNPACK_CTRL,
621 VIU_OSD2_DIMM_CTRL,
622 VPP_WRAP_OSD2_MATRIX_EN_CTRL,
623
624 T7_OSD2_SCALE_COEF_IDX,
625 T7_OSD2_SCALE_COEF,
626 T7_OSD2_VSC_PHASE_STEP,
627 T7_OSD2_VSC_INI_PHASE,
628 T7_OSD2_VSC_CTRL0,
629 T7_OSD2_HSC_PHASE_STEP,
630 T7_OSD2_HSC_INI_PHASE,
631 T7_OSD2_HSC_CTRL0,
632 T7_OSD2_SC_DUMMY_DATA,
633 T7_OSD2_SC_CTRL0,
634 T7_OSD2_SCI_WH_M1,
635 T7_OSD2_SCO_H_START_END,
636 T7_OSD2_SCO_V_START_END,
637 OSD2_DB_FLT_CTRL,
638 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1,
639 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1,
640 VPU_MAFBC_FORMAT_SPECIFIER_S1,
641 VPU_MAFBC_BUFFER_WIDTH_S1,
642 VPU_MAFBC_BUFFER_HEIGHT_S1,
643 VPU_MAFBC_BOUNDING_BOX_X_START_S1,
644 VPU_MAFBC_BOUNDING_BOX_X_END_S1,
645 VPU_MAFBC_BOUNDING_BOX_Y_START_S1,
646 VPU_MAFBC_BOUNDING_BOX_Y_END_S1,
647 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1,
648 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1,
649 VPU_MAFBC_OUTPUT_BUF_STRIDE_S1,
650 VPU_MAFBC_PREFETCH_CFG_S1,
651
652 MALI_AFBCD_TOP_CTRL,
653 VPU_MAFBC_IRQ_MASK,
654 VPU_MAFBC_SURFACE_CFG,
655 VPU_MAFBC_COMMAND,
656 VPU_MAFBC_IRQ_RAW_STATUS,
657 VPU_MAFBC_IRQ_CLEAR,
658
659 VPP_OSD2_SCALE_CTRL,
660 },
661 {
662 VIU_OSD3_CTRL_STAT,
663 VIU_OSD3_CTRL_STAT2,
664 VIU_OSD3_COLOR_ADDR,
665 VIU_OSD3_COLOR,
666 VIU_OSD3_TCOLOR_AG0,
667 VIU_OSD3_TCOLOR_AG1,
668 VIU_OSD3_TCOLOR_AG2,
669 VIU_OSD3_TCOLOR_AG3,
670 VIU_OSD3_BLK0_CFG_W0,
671 VIU_OSD3_BLK0_CFG_W1,
672 VIU_OSD3_BLK0_CFG_W2,
673 VIU_OSD3_BLK0_CFG_W3,
674 VIU_OSD3_BLK0_CFG_W4,
675 VIU_OSD3_BLK1_CFG_W4,
676 VIU_OSD3_BLK2_CFG_W4,
677 VIU_OSD3_FIFO_CTRL_STAT,
678 VIU_OSD3_TEST_RDDATA,
679 VIU_OSD3_PROT_CTRL,
680 VIU_OSD3_MALI_UNPACK_CTRL,
681 VIU_OSD3_DIMM_CTRL,
682 VPP_WRAP_OSD3_MATRIX_EN_CTRL,
683
684 T7_OSD34_SCALE_COEF_IDX,
685 T7_OSD34_SCALE_COEF,
686 T7_OSD34_VSC_PHASE_STEP,
687 T7_OSD34_VSC_INI_PHASE,
688 T7_OSD34_VSC_CTRL0,
689 T7_OSD34_HSC_PHASE_STEP,
690 T7_OSD34_HSC_INI_PHASE,
691 T7_OSD34_HSC_CTRL0,
692 T7_OSD34_SC_DUMMY_DATA,
693 T7_OSD34_SC_CTRL0,
694 T7_OSD34_SCI_WH_M1,
695 T7_OSD34_SCO_H_START_END,
696 T7_OSD34_SCO_V_START_END,
697 OSD34_DB_FLT_CTRL,
698 VPU_MAFBC1_HEADER_BUF_ADDR_LOW_S2,
699 VPU_MAFBC1_HEADER_BUF_ADDR_HIGH_S2,
700 VPU_MAFBC1_FORMAT_SPECIFIER_S2,
701 VPU_MAFBC1_BUFFER_WIDTH_S2,
702 VPU_MAFBC1_BUFFER_HEIGHT_S2,
703 VPU_MAFBC1_BOUNDING_BOX_X_START_S2,
704 VPU_MAFBC1_BOUNDING_BOX_X_END_S2,
705 VPU_MAFBC1_BOUNDING_BOX_Y_START_S2,
706 VPU_MAFBC1_BOUNDING_BOX_Y_END_S2,
707 VPU_MAFBC1_OUTPUT_BUF_ADDR_LOW_S2,
708 VPU_MAFBC1_OUTPUT_BUF_ADDR_HIGH_S2,
709 VPU_MAFBC1_OUTPUT_BUF_STRIDE_S2,
710 VPU_MAFBC1_PREFETCH_CFG_S2,
711
712 MALI_AFBCD1_TOP_CTRL,
713 VPU_MAFBC1_IRQ_MASK,
714 VPU_MAFBC1_SURFACE_CFG,
715 VPU_MAFBC1_COMMAND,
716 VPU_MAFBC1_IRQ_RAW_STATUS,
717 VPU_MAFBC1_IRQ_CLEAR,
718
719 VPP_OSD3_SCALE_CTRL,
720 },
721 {
722 VIU_OSD4_CTRL_STAT,
723 VIU_OSD4_CTRL_STAT2,
724 VIU_OSD4_COLOR_ADDR,
725 VIU_OSD4_COLOR,
726 VIU_OSD4_TCOLOR_AG0,
727 VIU_OSD4_TCOLOR_AG1,
728 VIU_OSD4_TCOLOR_AG2,
729 VIU_OSD4_TCOLOR_AG3,
730 VIU_OSD4_BLK0_CFG_W0,
731 VIU_OSD4_BLK0_CFG_W1,
732 VIU_OSD4_BLK0_CFG_W2,
733 VIU_OSD4_BLK0_CFG_W3,
734 VIU_OSD4_BLK0_CFG_W4,
735 VIU_OSD4_BLK1_CFG_W4,
736 VIU_OSD4_BLK2_CFG_W4,
737 VIU_OSD4_FIFO_CTRL_STAT,
738 VIU_OSD4_TEST_RDDATA,
739 VIU_OSD4_PROT_CTRL,
740 VIU_OSD4_MALI_UNPACK_CTRL,
741 VIU_OSD4_DIMM_CTRL,
742 VIU_OSD4_MATRIX_EN_CTRL,
743
744 T7_OSD4_SCALE_COEF_IDX,
745 T7_OSD4_SCALE_COEF,
746 T7_OSD4_VSC_PHASE_STEP,
747 T7_OSD4_VSC_INI_PHASE,
748 T7_OSD4_VSC_CTRL0,
749 T7_OSD4_HSC_PHASE_STEP,
750 T7_OSD4_HSC_INI_PHASE,
751 T7_OSD4_HSC_CTRL0,
752 T7_OSD4_SC_DUMMY_DATA,
753 T7_OSD4_SC_CTRL0,
754 T7_OSD4_SCI_WH_M1,
755 T7_OSD4_SCO_H_START_END,
756 T7_OSD4_SCO_V_START_END,
757 OSD4_DB_FLT_CTRL,
758 VPU_MAFBC2_HEADER_BUF_ADDR_LOW_S3,
759 VPU_MAFBC2_HEADER_BUF_ADDR_HIGH_S3,
760 VPU_MAFBC2_FORMAT_SPECIFIER_S3,
761 VPU_MAFBC2_BUFFER_WIDTH_S3,
762 VPU_MAFBC2_BUFFER_HEIGHT_S3,
763 VPU_MAFBC2_BOUNDING_BOX_X_START_S3,
764 VPU_MAFBC2_BOUNDING_BOX_X_END_S3,
765 VPU_MAFBC2_BOUNDING_BOX_Y_START_S3,
766 VPU_MAFBC2_BOUNDING_BOX_Y_END_S3,
767 VPU_MAFBC2_OUTPUT_BUF_ADDR_LOW_S3,
768 VPU_MAFBC2_OUTPUT_BUF_ADDR_HIGH_S3,
769 VPU_MAFBC2_OUTPUT_BUF_STRIDE_S3,
770 VPU_MAFBC2_PREFETCH_CFG_S3,
771
772 MALI_AFBCD2_TOP_CTRL,
773 VPU_MAFBC2_IRQ_MASK,
774 VPU_MAFBC2_SURFACE_CFG,
775 VPU_MAFBC2_COMMAND,
776 VPU_MAFBC2_IRQ_RAW_STATUS,
777 VPU_MAFBC2_IRQ_CLEAR,
778
779 VPP_OSD4_SCALE_CTRL,
780 },
781};
782
783struct hw_osd_reg_s hw_osd_reg_array_t3[HW_OSD_COUNT] = {
784 {
785 VIU_OSD1_CTRL_STAT,
786 VIU_OSD1_CTRL_STAT2,
787 VIU_OSD1_COLOR_ADDR,
788 VIU_OSD1_COLOR,
789 VIU_OSD1_TCOLOR_AG0,
790 VIU_OSD1_TCOLOR_AG1,
791 VIU_OSD1_TCOLOR_AG2,
792 VIU_OSD1_TCOLOR_AG3,
793 VIU_OSD1_BLK0_CFG_W0,
794 VIU_OSD1_BLK0_CFG_W1,
795 VIU_OSD1_BLK0_CFG_W2,
796 VIU_OSD1_BLK0_CFG_W3,
797 VIU_OSD1_BLK0_CFG_W4,
798 VIU_OSD1_BLK1_CFG_W4,
799 VIU_OSD1_BLK2_CFG_W4,
800 VIU_OSD1_FIFO_CTRL_STAT,
801 VIU_OSD1_TEST_RDDATA,
802 VIU_OSD1_PROT_CTRL,
803 VIU_OSD1_MALI_UNPACK_CTRL,
804 VIU_OSD1_DIMM_CTRL,
805 VPP_WRAP_OSD1_MATRIX_EN_CTRL,
806
807 T7_VPP_OSD_SCALE_COEF_IDX,
808 T7_VPP_OSD_SCALE_COEF,
809 T7_VPP_OSD_VSC_PHASE_STEP,
810 T7_VPP_OSD_VSC_INI_PHASE,
811 T7_VPP_OSD_VSC_CTRL0,
812 T7_VPP_OSD_HSC_PHASE_STEP,
813 T7_VPP_OSD_HSC_INI_PHASE,
814 T7_VPP_OSD_HSC_CTRL0,
815 T7_VPP_OSD_SC_DUMMY_DATA,
816 T7_VPP_OSD_SC_CTRL0,
817 T7_VPP_OSD_SCI_WH_M1,
818 T7_VPP_OSD_SCO_H_START_END,
819 T7_VPP_OSD_SCO_V_START_END,
820 OSD_DB_FLT_CTRL,
821 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0,
822 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0,
823 VPU_MAFBC_FORMAT_SPECIFIER_S0,
824 VPU_MAFBC_BUFFER_WIDTH_S0,
825 VPU_MAFBC_BUFFER_HEIGHT_S0,
826 VPU_MAFBC_BOUNDING_BOX_X_START_S0,
827 VPU_MAFBC_BOUNDING_BOX_X_END_S0,
828 VPU_MAFBC_BOUNDING_BOX_Y_START_S0,
829 VPU_MAFBC_BOUNDING_BOX_Y_END_S0,
830 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0,
831 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0,
832 VPU_MAFBC_OUTPUT_BUF_STRIDE_S0,
833 VPU_MAFBC_PREFETCH_CFG_S0,
834
835 VIU_OSD1_PATH_CTRL,
836 VPU_MAFBC_IRQ_MASK,
837 VPU_MAFBC_SURFACE_CFG,
838 VPU_MAFBC_COMMAND,
839 VPU_MAFBC_IRQ_RAW_STATUS,
840 VPU_MAFBC_IRQ_CLEAR,
841
842 VIU_OSD1_PATH_CTRL,
843 },
844 {
845 VIU_OSD2_CTRL_STAT,
846 VIU_OSD2_CTRL_STAT2,
847 VIU_OSD2_COLOR_ADDR,
848 VIU_OSD2_COLOR,
849 VIU_OSD2_TCOLOR_AG0,
850 VIU_OSD2_TCOLOR_AG1,
851 VIU_OSD2_TCOLOR_AG2,
852 VIU_OSD2_TCOLOR_AG3,
853 VIU_OSD2_BLK0_CFG_W0,
854 VIU_OSD2_BLK0_CFG_W1,
855 VIU_OSD2_BLK0_CFG_W2,
856 VIU_OSD2_BLK0_CFG_W3,
857 VIU_OSD2_BLK0_CFG_W4,
858 VIU_OSD2_BLK1_CFG_W4,
859 VIU_OSD2_BLK2_CFG_W4,
860 VIU_OSD2_FIFO_CTRL_STAT,
861 VIU_OSD2_TEST_RDDATA,
862 VIU_OSD2_PROT_CTRL,
863 VIU_OSD2_MALI_UNPACK_CTRL,
864 VIU_OSD2_DIMM_CTRL,
865 VPP_WRAP_OSD2_MATRIX_EN_CTRL,
866
867 T7_OSD2_SCALE_COEF_IDX,
868 T7_OSD2_SCALE_COEF,
869 T7_OSD2_VSC_PHASE_STEP,
870 T7_OSD2_VSC_INI_PHASE,
871 T7_OSD2_VSC_CTRL0,
872 T7_OSD2_HSC_PHASE_STEP,
873 T7_OSD2_HSC_INI_PHASE,
874 T7_OSD2_HSC_CTRL0,
875 T7_OSD2_SC_DUMMY_DATA,
876 T7_OSD2_SC_CTRL0,
877 T7_OSD2_SCI_WH_M1,
878 T7_OSD2_SCO_H_START_END,
879 T7_OSD2_SCO_V_START_END,
880 OSD2_DB_FLT_CTRL,
881 VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1,
882 VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1,
883 VPU_MAFBC_FORMAT_SPECIFIER_S1,
884 VPU_MAFBC_BUFFER_WIDTH_S1,
885 VPU_MAFBC_BUFFER_HEIGHT_S1,
886 VPU_MAFBC_BOUNDING_BOX_X_START_S1,
887 VPU_MAFBC_BOUNDING_BOX_X_END_S1,
888 VPU_MAFBC_BOUNDING_BOX_Y_START_S1,
889 VPU_MAFBC_BOUNDING_BOX_Y_END_S1,
890 VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1,
891 VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1,
892 VPU_MAFBC_OUTPUT_BUF_STRIDE_S1,
893 VPU_MAFBC_PREFETCH_CFG_S1,
894
895 VIU_OSD2_PATH_CTRL,
896 VPU_MAFBC_IRQ_MASK,
897 VPU_MAFBC_SURFACE_CFG,
898 VPU_MAFBC_COMMAND,
899 VPU_MAFBC_IRQ_RAW_STATUS,
900 VPU_MAFBC_IRQ_CLEAR,
901
902 VIU_OSD2_PATH_CTRL,
903 },
904 {
905 VIU_OSD3_CTRL_STAT,
906 VIU_OSD3_CTRL_STAT2,
907 VIU_OSD3_COLOR_ADDR,
908 VIU_OSD3_COLOR,
909 VIU_OSD3_TCOLOR_AG0,
910 VIU_OSD3_TCOLOR_AG1,
911 VIU_OSD3_TCOLOR_AG2,
912 VIU_OSD3_TCOLOR_AG3,
913 VIU_OSD3_BLK0_CFG_W0,
914 VIU_OSD3_BLK0_CFG_W1,
915 VIU_OSD3_BLK0_CFG_W2,
916 VIU_OSD3_BLK0_CFG_W3,
917 VIU_OSD3_BLK0_CFG_W4,
918 VIU_OSD3_BLK1_CFG_W4,
919 VIU_OSD3_BLK2_CFG_W4,
920 VIU_OSD3_FIFO_CTRL_STAT,
921 VIU_OSD3_TEST_RDDATA,
922 VIU_OSD3_PROT_CTRL,
923 VIU_OSD3_MALI_UNPACK_CTRL,
924 VIU_OSD3_DIMM_CTRL,
925 VPP_WRAP_OSD3_MATRIX_EN_CTRL,
926
927 T7_OSD34_SCALE_COEF_IDX,
928 T7_OSD34_SCALE_COEF,
929 T7_OSD34_VSC_PHASE_STEP,
930 T7_OSD34_VSC_INI_PHASE,
931 T7_OSD34_VSC_CTRL0,
932 T7_OSD34_HSC_PHASE_STEP,
933 T7_OSD34_HSC_INI_PHASE,
934 T7_OSD34_HSC_CTRL0,
935 T7_OSD34_SC_DUMMY_DATA,
936 T7_OSD34_SC_CTRL0,
937 T7_OSD34_SCI_WH_M1,
938 T7_OSD34_SCO_H_START_END,
939 T7_OSD34_SCO_V_START_END,
940 OSD34_DB_FLT_CTRL,
941 VPU_MAFBC1_HEADER_BUF_ADDR_LOW_S2,
942 VPU_MAFBC1_HEADER_BUF_ADDR_HIGH_S2,
943 VPU_MAFBC1_FORMAT_SPECIFIER_S2,
944 VPU_MAFBC1_BUFFER_WIDTH_S2,
945 VPU_MAFBC1_BUFFER_HEIGHT_S2,
946 VPU_MAFBC1_BOUNDING_BOX_X_START_S2,
947 VPU_MAFBC1_BOUNDING_BOX_X_END_S2,
948 VPU_MAFBC1_BOUNDING_BOX_Y_START_S2,
949 VPU_MAFBC1_BOUNDING_BOX_Y_END_S2,
950 VPU_MAFBC1_OUTPUT_BUF_ADDR_LOW_S2,
951 VPU_MAFBC1_OUTPUT_BUF_ADDR_HIGH_S2,
952 VPU_MAFBC1_OUTPUT_BUF_STRIDE_S2,
953 VPU_MAFBC1_PREFETCH_CFG_S2,
954
955 VIU_OSD3_PATH_CTRL,
956 VPU_MAFBC1_IRQ_MASK,
957 VPU_MAFBC1_SURFACE_CFG,
958 VPU_MAFBC1_COMMAND,
959 VPU_MAFBC1_IRQ_RAW_STATUS,
960 VPU_MAFBC1_IRQ_CLEAR,
961
962 VIU_OSD3_PATH_CTRL,
963 },
964};
965
Googler9726be62022-12-14 05:53:31 +0000966#define VIU2_OSD_REG_NUM 13
967static u32 viu2_osd_table[VIU2_OSD_REG_NUM];
968static struct viu2_osd_reg_item viu2_osd_reg_table[VIU2_OSD_REG_NUM] = {
969 {VIU2_OSD1_CTRL_STAT, 0, 0xc01ff9f7},
970 {VIU2_OSD1_CTRL_STAT2, 0x0, 0x00007fff},
971 {VIU2_OSD1_BLK0_CFG_W0, 0x0, 0x70ffff7f},
972 {VIU2_OSD1_BLK0_CFG_W1, 0x0, 0x1fff1fff},
973 {VIU2_OSD1_BLK0_CFG_W2, 0x0, 0x1fff1fff},
974 {VIU2_OSD1_BLK0_CFG_W3, 0x0, 0x0fff0fff},
975 {VIU2_OSD1_BLK0_CFG_W4, 0x0, 0x0fff0fff},
976 {VIU2_OSD1_BLK1_CFG_W4, 0x0, 0xffffffff},
977 {VIU2_OSD1_BLK2_CFG_W4, 0x0, 0xffffffff},
978 {VIU2_OSD1_FIFO_CTRL_STAT, 0x0, 0xffc7ffff},
979 {VIU2_OSD1_PROT_CTRL, 0x0, 0xffff0000},
980 {VIU2_OSD1_MALI_UNPACK_CTRL, 0x0, 0x9f01ffff},
981 {VIU2_OSD1_DIMM_CTRL, 0x0, 0x7fffffff},
982};
983
984struct affinity_info_s {
985 struct completion affinity_task_com;
986 struct cpumask cpu_mask;
987 int run_affinity_task;
988 unsigned long affinity_mask;
989};
990
Googler4f18c0c2022-09-20 17:23:36 +0800991static int osd_setting_blending_scope(u32 index);
992static int vpp_blend_setting_default(u32 index);
993
994#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
Googler9726be62022-12-14 05:53:31 +0000995static struct affinity_info_s affinity_info;
Googler9398cc32022-12-02 17:21:52 +0800996/* sync fence relative variable. */
Googler4f18c0c2022-09-20 17:23:36 +0800997static int timeline_created[VIU_COUNT];
998static void *osd_timeline[VIU_COUNT];
999static u32 cur_streamline_val[VIU_COUNT];
1000/* thread control part */
1001struct kthread_worker buffer_toggle_worker[VIU_COUNT];
1002struct task_struct *buffer_toggle_thread[VIU_COUNT];
1003struct kthread_work buffer_toggle_work[VIU_COUNT];
1004struct list_head post_fence_list[VIU_COUNT];
Googler9398cc32022-12-02 17:21:52 +08001005struct mutex post_fence_list_lock[VIU_COUNT];/* fence mutex */
Googler4f18c0c2022-09-20 17:23:36 +08001006struct osd_layers_fence_map_s map_layers[VIU_COUNT];
1007struct file *displayed_bufs[HW_OSD_COUNT];
Googler9398cc32022-12-02 17:21:52 +08001008static void osd_pan_display_single_fence
1009 (struct osd_fence_map_s *fence_map);
1010static void osd_pan_display_layers_fence
1011 (struct osd_layers_fence_map_s *fence_map);
1012static void osd_pan_display_single_fence_viu2
1013 (struct osd_fence_map_s *fence_map);
1014static void osd_pan_display_layers_fence_viu2
1015 (struct osd_layers_fence_map_s *fence_map);
Googler4f18c0c2022-09-20 17:23:36 +08001016
1017static void *osd_timeline_create(u32 output_index)
1018{
1019 char tlname[32] = {};
1020
1021 sprintf(tlname, "osd_timeline_%d", output_index);
1022 if (!osd_timeline[output_index]) {
1023 if (osd_hw.hwc_enable[output_index])
1024 /* present fence */
1025 cur_streamline_val[output_index] = 0;
1026 else
1027 cur_streamline_val[output_index] = 1;
1028 osd_timeline[output_index] = aml_sync_create_timeline(tlname);
1029 osd_tprintk("osd timeline create\n");
1030 }
Googler9398cc32022-12-02 17:21:52 +08001031
Googler4f18c0c2022-09-20 17:23:36 +08001032 return osd_timeline[output_index];
1033}
1034
1035static int osd_timeline_create_fence(u32 output_index)
1036{
1037 int out_fence_fd = -1;
1038 u32 pt_val = 0;
1039
1040 pt_val = cur_streamline_val[output_index] + 1;
1041 out_fence_fd = aml_sync_create_fence
1042 (osd_timeline[output_index], pt_val);
1043 osd_tprintk("osd created out pt:%d, fence_fd:%d\n",
Googler9398cc32022-12-02 17:21:52 +08001044 pt_val, out_fence_fd);
Googler4f18c0c2022-09-20 17:23:36 +08001045
1046 if (out_fence_fd >= 0)
1047 cur_streamline_val[output_index]++;
1048 else
1049 pr_info("create fence returned %d", out_fence_fd);
1050 return out_fence_fd;
1051}
1052
1053static void osd_timeline_increase(u32 output_index)
1054{
1055 aml_sync_inc_timeline(osd_timeline[output_index], 1);
1056 osd_tprintk("osd out timeline %d inc\n", output_index);
Googler4f18c0c2022-09-20 17:23:36 +08001057}
1058
Googler9398cc32022-12-02 17:21:52 +08001059static struct dma_fence *osd_get_fenceobj(int fencefd)
Googler4f18c0c2022-09-20 17:23:36 +08001060{
Googler9398cc32022-12-02 17:21:52 +08001061 struct dma_fence *syncobj = NULL;
Googler4f18c0c2022-09-20 17:23:36 +08001062
1063 if (fencefd < 0)
1064 return NULL;
1065
1066 syncobj = aml_sync_get_fence(fencefd);
1067 osd_tprintk("osd get in fence%p, fd:%d\n", syncobj, fencefd);
1068
1069 return syncobj;
1070}
1071
Googler9398cc32022-12-02 17:21:52 +08001072static int osd_wait_fenceobj(struct dma_fence *fence, long timeout)
Googler4f18c0c2022-09-20 17:23:36 +08001073{
1074 osd_tprintk("osd wait in fence%p\n", fence);
1075 return aml_sync_wait_fence(fence, timeout);
1076}
1077
Googler9398cc32022-12-02 17:21:52 +08001078static void osd_put_fenceobj(struct dma_fence *fence)
Googler4f18c0c2022-09-20 17:23:36 +08001079{
1080 osd_tprintk("osd put fence\n");
1081 aml_sync_put_fence(fence);
1082}
1083
1084#endif
1085
1086static int pxp_mode;
Googler9726be62022-12-14 05:53:31 +00001087s64 timestamp[VIU_COUNT];
Googler4f18c0c2022-09-20 17:23:36 +08001088
1089static unsigned int osd_h_filter_mode = 1;
1090#define BYTE_32_ALIGNED(x) (((x) + 31) & ~31)
1091#define BYTE_16_ALIGNED(x) (((x) + 15) & ~15)
1092#define BYTE_8_ALIGNED(x) (((x) + 7) & ~7)
1093module_param(osd_h_filter_mode, uint, 0664);
1094MODULE_PARM_DESC(osd_h_filter_mode, "osd_h_filter_mode");
1095
1096static unsigned int osd_v_filter_mode = 1;
1097module_param(osd_v_filter_mode, uint, 0664);
1098MODULE_PARM_DESC(osd_v_filter_mode, "osd_v_filter_mode");
1099
1100static unsigned int osd_auto_adjust_filter = 1;
1101module_param(osd_auto_adjust_filter, uint, 0664);
1102MODULE_PARM_DESC(osd_auto_adjust_filter, "osd_auto_adjust_filter");
1103
1104static int osd_logo_index = 1;
1105module_param(osd_logo_index, int, 0664);
1106MODULE_PARM_DESC(osd_logo_index, "osd_logo_index");
1107
1108module_param(osd_afbc_dec_enable, int, 0664);
1109MODULE_PARM_DESC(osd_afbc_dec_enable, "osd_afbc_dec_enable");
1110
1111static u32 osd_vpp_misc;
1112static u32 osd_vpp_misc_mask = OSD_RELATIVE_BITS;
Googler9398cc32022-12-02 17:21:52 +08001113static u32 osd_vpp1_bld_ctrl;
1114static u32 osd_vpp1_bld_ctrl_mask = 0x30;
1115static u32 osd_vpp2_bld_ctrl;
1116static u32 osd_vpp2_bld_ctrl_mask = 0x30;
1117/* indicates whether vpp1&vpp2 has been notified or not */
1118static u32 osd_vpp_bld_ctrl_update_mask = 0x80000000;
1119
Googler4f18c0c2022-09-20 17:23:36 +08001120module_param(osd_vpp_misc, uint, 0444);
1121MODULE_PARM_DESC(osd_vpp_misc, "osd_vpp_misc");
1122
1123static unsigned int rdarb_reqen_slv = 0xff7f;
1124module_param(rdarb_reqen_slv, uint, 0664);
1125MODULE_PARM_DESC(rdarb_reqen_slv, "rdarb_reqen_slv");
1126
1127static unsigned int supsend_delay;
1128module_param(supsend_delay, uint, 0664);
1129MODULE_PARM_DESC(supsend_delay, "supsend_delay");
1130
1131int enable_vd_zorder = 1;
1132MODULE_PARM_DESC(enable_vd_zorder, "\n enable_vd_zorder\n");
1133module_param(enable_vd_zorder, uint, 0664);
Googler4f18c0c2022-09-20 17:23:36 +08001134static int vsync_enter_line_max;
1135static int vsync_exit_line_max;
Googler9726be62022-12-14 05:53:31 +00001136static int line_threshold = 5;
1137static int line_threshold_2 = 90;
1138static int vsync_threshold = 10;
1139static int vsync_adjust_hit;
Googler9398cc32022-12-02 17:21:52 +08001140
1141module_param_named(osd_vsync_enter_line_max, vsync_enter_line_max, uint, 0664);
1142
1143module_param_named(osd_vsync_exit_line_max, vsync_exit_line_max, uint, 0664);
1144
Googler4f18c0c2022-09-20 17:23:36 +08001145MODULE_PARM_DESC(line_threshold, "\n line_threshold\n");
1146module_param(line_threshold, uint, 0664);
Googler9726be62022-12-14 05:53:31 +00001147MODULE_PARM_DESC(line_threshold_2, "\n line_threshold_2\n");
1148module_param(line_threshold_2, uint, 0664);
1149MODULE_PARM_DESC(vsync_threshold, "\n vsync_threshold\n");
1150module_param(vsync_threshold, uint, 0664);
1151MODULE_PARM_DESC(vsync_adjust_hit, "\n vsync_adjust_hit\n");
1152module_param(vsync_adjust_hit, uint, 0664);
1153
Googler4f18c0c2022-09-20 17:23:36 +08001154static unsigned int osd_filter_coefs_bicubic_sharp[] = {
1155 0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300,
1156 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900,
1157 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
1158 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe,
1159 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd,
1160 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
1161 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa,
1162 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9,
1163 0xf84848f8
1164};
1165
1166static unsigned int osd_filter_coefs_bicubic[] = { /* bicubic coef0 */
1167 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, 0xfd7e0500, 0xfc7e0600,
1168 0xfb7d0800, 0xfb7c0900, 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff,
1169 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, 0xf76f1dfd, 0xf76d1ffd,
1170 0xf76b21fd, 0xf76824fd, 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb,
1171 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, 0xf8523cfa, 0xf8503ff9,
1172 0xf84d42f9, 0xf84a45f9, 0xf84848f8
1173};
1174
1175static unsigned int osd_filter_coefs_bilinear[] = { /* 2 point bilinear coef1 */
1176 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, 0x00780800, 0x00760a00,
1177 0x00740c00, 0x00720e00, 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600,
1178 0x00681800, 0x00661a00, 0x00641c00, 0x00621e00, 0x00602000, 0x005e2200,
1179 0x005c2400, 0x005a2600, 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00,
1180 0x00503000, 0x004e3200, 0x004c3400, 0x004a3600, 0x00483800, 0x00463a00,
1181 0x00443c00, 0x00423e00, 0x00404000
1182};
1183
1184static unsigned int osd_filter_coefs_2point_binilear[] = {
1185 /* 2 point bilinear, bank_length == 2 coef2 */
1186 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, 0x78080000, 0x760a0000,
1187 0x740c0000, 0x720e0000, 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000,
1188 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, 0x60200000, 0x5e220000,
1189 0x5c240000, 0x5a260000, 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000,
1190 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, 0x48380000, 0x463a0000,
1191 0x443c0000, 0x423e0000, 0x40400000
1192};
1193
1194/* filt_triangle, point_num =3, filt_len =2.6, group_num = 64 */
1195static unsigned int osd_filter_coefs_3point_triangle_sharp[] = {
1196 0x40400000, 0x3e420000, 0x3d430000, 0x3b450000,
1197 0x3a460000, 0x38480000, 0x37490000, 0x354b0000,
1198 0x344c0000, 0x324e0000, 0x314f0000, 0x2f510000,
1199 0x2e520000, 0x2c540000, 0x2b550000, 0x29570000,
1200 0x28580000, 0x265a0000, 0x245c0000, 0x235d0000,
1201 0x215f0000, 0x20600000, 0x1e620000, 0x1d620100,
1202 0x1b620300, 0x19630400, 0x17630600, 0x15640700,
1203 0x14640800, 0x12640a00, 0x11640b00, 0x0f650c00,
1204 0x0d660d00
1205};
1206
1207static unsigned int osd_filter_coefs_3point_triangle[] = {
1208 0x40400000, 0x3f400100, 0x3d410200, 0x3c410300,
1209 0x3a420400, 0x39420500, 0x37430600, 0x36430700,
1210 0x35430800, 0x33450800, 0x32450900, 0x31450a00,
1211 0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00,
1212 0x2b470e00, 0x29480f00, 0x28481000, 0x27481100,
1213 0x26491100, 0x25491200, 0x24491300, 0x234a1300,
1214 0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600,
1215 0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900,
1216 0x1a4c1a00
1217};
1218
1219static unsigned int osd_filter_coefs_4point_triangle[] = {
1220 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101,
1221 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303,
1222 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505,
1223 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707,
1224 0x18382808, 0x18382808, 0x17372909, 0x17372909,
1225 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b,
1226 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d,
1227 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f,
1228 0x10303010
1229};
1230
1231/* 4th order (cubic) b-spline */
1232/* filt_cubic point_num =4, filt_len =4, group_num = 64 */
1233static unsigned int vpp_filter_coefs_4point_bspline[] = {
1234 0x15561500, 0x14561600, 0x13561700, 0x12561800,
1235 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,
1236 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200,
1237 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700,
1238 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01,
1239 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201,
1240 0x05473301, 0x05463401, 0x04453601, 0x04433702,
1241 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02,
1242 0x033d3d03
1243};
1244
1245/* filt_quadratic, point_num =3, filt_len =3, group_num = 64 */
1246static unsigned int osd_filter_coefs_3point_bspline[] = {
1247 0x40400000, 0x3e420000, 0x3c440000, 0x3a460000,
1248 0x38480000, 0x364a0000, 0x344b0100, 0x334c0100,
1249 0x314e0100, 0x304f0100, 0x2e500200, 0x2c520200,
1250 0x2a540200, 0x29540300, 0x27560300, 0x26570300,
1251 0x24580400, 0x23590400, 0x215a0500, 0x205b0500,
1252 0x1e5c0600, 0x1d5c0700, 0x1c5d0700, 0x1a5e0800,
1253 0x195e0900, 0x185e0a00, 0x175f0a00, 0x15600b00,
1254 0x14600c00, 0x13600d00, 0x12600e00, 0x11600f00,
1255 0x10601000
1256};
1257
Googler9726be62022-12-14 05:53:31 +00001258static unsigned int osd_filter_coefs_repeat[] = { /* repeat coef0 */
1259 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
1260 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
1261 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
1262 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
1263 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000,
1264 0x00800000, 0x00800000, 0x00800000
1265};
1266
Googler4f18c0c2022-09-20 17:23:36 +08001267static unsigned int *filter_table[] = {
1268 osd_filter_coefs_bicubic_sharp,
1269 osd_filter_coefs_bicubic,
1270 osd_filter_coefs_bilinear,
1271 osd_filter_coefs_2point_binilear,
1272 osd_filter_coefs_3point_triangle_sharp,
1273 osd_filter_coefs_3point_triangle,
1274 osd_filter_coefs_4point_triangle,
1275 vpp_filter_coefs_4point_bspline,
Googler9726be62022-12-14 05:53:31 +00001276 osd_filter_coefs_3point_bspline,
1277 osd_filter_coefs_repeat
Googler4f18c0c2022-09-20 17:23:36 +08001278};
1279
1280#ifdef NEW_PPS_PHASE
1281#define OSD_ZOOM_BITS 20
1282#define OSD_PHASE_BITS 16
1283
1284enum osd_f2v_vphase_type_e {
1285 OSD_F2V_IT2IT = 0,
1286 OSD_F2V_IB2IB,
1287 OSD_F2V_IT2IB,
1288 OSD_F2V_IB2IT,
1289 OSD_F2V_P2IT,
1290 OSD_F2V_P2IB,
1291 OSD_F2V_IT2P,
1292 OSD_F2V_IB2P,
1293 OSD_F2V_P2P,
1294 OSD_F2V_TYPE_MAX
1295};
1296
1297struct osd_f2v_vphase_s {
1298 u8 rcv_num;
1299 u8 rpt_num;
1300 u16 phase;
1301};
1302
1303#define COEFF_NORM(a) ((int)((((a) * 2048.0) + 1) / 2))
1304#define MATRIX_5x3_COEF_SIZE 24
1305
1306static int RGB709_to_YUV709l_coeff[MATRIX_5x3_COEF_SIZE] = {
1307 0, 0, 0, /* pre offset */
1308 COEFF_NORM(0.181873), COEFF_NORM(0.611831), COEFF_NORM(0.061765),
1309 COEFF_NORM(-0.100251), COEFF_NORM(-0.337249), COEFF_NORM(0.437500),
1310 COEFF_NORM(0.437500), COEFF_NORM(-0.397384), COEFF_NORM(-0.040116),
1311 0, 0, 0, /* 10'/11'/12' */
1312 0, 0, 0, /* 20'/21'/22' */
1313 64, 512, 512, /* offset */
1314 0, 0, 0 /* mode, right_shift, clip_en */
1315};
1316
Googler9726be62022-12-14 05:53:31 +00001317static int is_yuv_format(u32 format)
1318{
1319 int b_yuv = 0;
1320
1321 switch (format) {
1322 case COLOR_FMT_YUV422:
1323 case COLOR_FMT_YUV444:
1324 case COLOR_FMT_YUYV422:
1325 case COLOR_FMT_YVYU422:
1326 case COLOR_FMT_UYVY422:
1327 case COLOR_FMT_VYUY422:
1328 case COLOR_FMT_NV12:
1329 case COLOR_FMT_NV21:
1330 b_yuv = 1;
1331 break;
1332 default:
1333 break;
1334 }
1335 return b_yuv;
1336}
1337
Googler4f18c0c2022-09-20 17:23:36 +08001338/*for G12A, set osd3 matrix(10bit) RGB2YUV*/
1339static void set_viu2_rgb2yuv(bool on)
1340{
Googler9726be62022-12-14 05:53:31 +00001341 /* RGB -> 709 limit */
1342 int *m = RGB709_to_YUV709l_coeff;
Googler4f18c0c2022-09-20 17:23:36 +08001343
Googler9726be62022-12-14 05:53:31 +00001344 /* VPP WRAP OSD3 matrix */
1345 osd_reg_write(VIU2_OSD1_MATRIX_PRE_OFFSET0_1,
Googler9398cc32022-12-02 17:21:52 +08001346 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
Googler9726be62022-12-14 05:53:31 +00001347 osd_reg_write(VIU2_OSD1_MATRIX_PRE_OFFSET2,
Googler9398cc32022-12-02 17:21:52 +08001348 m[2] & 0xfff);
Googler9726be62022-12-14 05:53:31 +00001349 osd_reg_write(VIU2_OSD1_MATRIX_COEF00_01,
Googler9398cc32022-12-02 17:21:52 +08001350 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
Googler9726be62022-12-14 05:53:31 +00001351 osd_reg_write(VIU2_OSD1_MATRIX_COEF02_10,
Googler9398cc32022-12-02 17:21:52 +08001352 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
Googler9726be62022-12-14 05:53:31 +00001353 osd_reg_write(VIU2_OSD1_MATRIX_COEF11_12,
Googler9398cc32022-12-02 17:21:52 +08001354 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
Googler9726be62022-12-14 05:53:31 +00001355 osd_reg_write(VIU2_OSD1_MATRIX_COEF20_21,
Googler9398cc32022-12-02 17:21:52 +08001356 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
Googler9726be62022-12-14 05:53:31 +00001357 osd_reg_write(VIU2_OSD1_MATRIX_COEF22,
Googler9398cc32022-12-02 17:21:52 +08001358 m[11] & 0x1fff);
Googler4f18c0c2022-09-20 17:23:36 +08001359
Googler9726be62022-12-14 05:53:31 +00001360 osd_reg_write(VIU2_OSD1_MATRIX_OFFSET0_1,
Googler9398cc32022-12-02 17:21:52 +08001361 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
Googler9726be62022-12-14 05:53:31 +00001362 osd_reg_write(VIU2_OSD1_MATRIX_OFFSET2,
Googler9398cc32022-12-02 17:21:52 +08001363 m[20] & 0xfff);
Googler4f18c0c2022-09-20 17:23:36 +08001364
Googler9726be62022-12-14 05:53:31 +00001365 osd_reg_set_bits(VIU2_OSD1_MATRIX_EN_CTRL, on, 0, 1);
Googler4f18c0c2022-09-20 17:23:36 +08001366}
1367
Googler9398cc32022-12-02 17:21:52 +08001368static void f2v_get_vertical_phase(u32 zoom_ratio,
1369 enum osd_f2v_vphase_type_e type,
1370 u8 bank_length,
1371 struct osd_f2v_vphase_s *vphase)
Googler4f18c0c2022-09-20 17:23:36 +08001372{
1373 u8 f2v_420_in_pos_luma[OSD_F2V_TYPE_MAX] = {
1374 0, 2, 0, 2, 0, 0, 0, 2, 0};
1375 u8 f2v_420_out_pos[OSD_F2V_TYPE_MAX] = {
1376 0, 2, 2, 0, 0, 2, 0, 0, 0};
1377 s32 offset_in, offset_out;
1378
1379 /* luma */
1380 offset_in = f2v_420_in_pos_luma[type]
1381 << OSD_PHASE_BITS;
1382 offset_out = (f2v_420_out_pos[type] * zoom_ratio)
1383 >> (OSD_ZOOM_BITS - OSD_PHASE_BITS);
1384
1385 vphase->rcv_num = bank_length;
1386 if (bank_length == 4 || bank_length == 3)
1387 vphase->rpt_num = 1;
1388 else
1389 vphase->rpt_num = 0;
1390
1391 if (offset_in > offset_out) {
1392 vphase->rpt_num = vphase->rpt_num + 1;
1393 vphase->phase =
1394 ((4 << OSD_PHASE_BITS) + offset_out - offset_in)
1395 >> 2;
1396 } else {
1397 while ((offset_in + (4 << OSD_PHASE_BITS))
1398 <= offset_out) {
1399 if (vphase->rpt_num == 1)
1400 vphase->rpt_num = 0;
1401 else
1402 vphase->rcv_num++;
1403 offset_in += 4 << OSD_PHASE_BITS;
1404 }
1405 vphase->phase = (offset_out - offset_in) >> 2;
1406 }
1407}
1408#endif
1409
1410#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
1411static bool osd_hdr_on;
1412#endif
Googler9726be62022-12-14 05:53:31 +00001413static bool is_encp(u32 viu_type)
Googler38bda472022-08-19 10:07:08 -07001414{
Googler9726be62022-12-14 05:53:31 +00001415 u32 viu = VIU1;
1416 bool ret = false;
Googler38bda472022-08-19 10:07:08 -07001417
Googler9726be62022-12-14 05:53:31 +00001418 if (viu_type == VIU1)
1419 viu = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3;
1420 else if (viu_type == VIU2)
1421 viu = (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) >> 2) & 0x3;
1422 if (viu == 2)
1423 /* encpi case, for 1080i */
1424 ret = true;
1425 /* for cvbs is enci */
1426 return ret;
1427}
1428
Googler9398cc32022-12-02 17:21:52 +08001429static int get_venc_type(u32 viu_type)
1430{
1431 u32 venc_type = 0;
1432
1433 if (osd_dev_hw.t7_display) {
1434 u32 venc_mux = 3;
1435 u32 venc_addr = VPU_VENC_CTRL;
1436
1437 venc_mux = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3f;
1438 venc_mux >>= (viu_type * 2);
1439 venc_mux &= 0x3;
1440
1441 switch (venc_mux) {
1442 case 0:
1443 venc_addr = VPU_VENC_CTRL;
1444 break;
1445 case 1:
1446 venc_addr = VPU1_VENC_CTRL;
1447 break;
1448 case 2:
1449 venc_addr = VPU2_VENC_CTRL;
1450 break;
1451 }
1452 venc_type = osd_reg_read(venc_addr);
1453 } else {
1454 if (viu_type == VIU1)
1455 venc_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL);
1456 else if (viu_type == VIU2)
1457 venc_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) >> 2;
1458 }
1459
1460 venc_type &= 0x3;
1461
1462 return venc_type;
1463}
1464
Googler9726be62022-12-14 05:53:31 +00001465static int get_active_begin_line(u32 viu_type)
1466{
1467 int active_line_begin = 0;
Googler9398cc32022-12-02 17:21:52 +08001468 u32 offset = 0;
1469 u32 reg = ENCL_VIDEO_VAVON_BLINE;
Googler9726be62022-12-14 05:53:31 +00001470
Googler9398cc32022-12-02 17:21:52 +08001471 if (osd_dev_hw.t7_display) {
1472 u32 venc_mux = 3;
1473
1474 venc_mux = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3f;
1475 venc_mux >>= (viu_type * 2);
1476 venc_mux &= 0x3;
1477
1478 switch (venc_mux) {
1479 case 0:
1480 offset = 0;
1481 break;
1482 case 1:
1483 offset = 0x600;
1484 break;
1485 case 2:
1486 offset = 0x800;
1487 break;
1488 }
1489 switch (get_venc_type(viu_type)) {
1490 case 0:
1491 reg = ENCI_VFIFO2VD_LINE_TOP_START;
1492 break;
1493 case 1:
1494 reg = ENCP_VIDEO_VAVON_BLINE;
1495 break;
1496 case 2:
1497 reg = ENCL_VIDEO_VAVON_BLINE;
1498 break;
1499 }
1500
1501 } else {
1502 switch (get_venc_type(viu_type)) {
1503 case 0:
1504 reg = ENCL_VIDEO_VAVON_BLINE;
1505 break;
1506 case 1:
1507 reg = ENCI_VFIFO2VD_LINE_TOP_START;
1508 break;
1509 case 2:
1510 reg = ENCP_VIDEO_VAVON_BLINE;
1511 break;
1512 case 3:
1513 reg = ENCT_VIDEO_VAVON_BLINE;
1514 break;
1515 }
Googler38bda472022-08-19 10:07:08 -07001516 }
Googler9726be62022-12-14 05:53:31 +00001517
Googler9398cc32022-12-02 17:21:52 +08001518 active_line_begin = osd_reg_read(reg + offset);
1519
Googler9726be62022-12-14 05:53:31 +00001520 return active_line_begin;
1521}
1522
1523static int get_encp_line(u32 viu_type)
1524{
1525 int enc_line = 0;
Googler9398cc32022-12-02 17:21:52 +08001526 unsigned int reg = VPU_VENCI_STAT;
1527 unsigned int reg_val = 0;
1528 u32 offset = 0;
1529 u32 venc_type = get_venc_type(viu_type);
Googler9726be62022-12-14 05:53:31 +00001530
Googler9398cc32022-12-02 17:21:52 +08001531 if (osd_dev_hw.t7_display) {
1532 u32 venc_mux = 3;
1533
1534 venc_mux = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3f;
1535 venc_mux >>= (viu_type * 2);
1536 venc_mux &= 0x3;
1537 switch (venc_mux) {
1538 case 0:
1539 offset = 0;
1540 break;
1541 case 1:
1542 offset = 0x600;
1543 break;
1544 case 2:
1545 offset = 0x800;
1546 break;
1547 }
1548 switch (venc_type) {
1549 case 0:
1550 reg = VPU_VENCI_STAT;
1551 break;
1552 case 1:
1553 reg = VPU_VENCP_STAT;
1554 break;
1555 case 2:
1556 reg = VPU_VENCL_STAT;
1557 break;
1558 }
1559 } else {
1560 switch (venc_type) {
1561 case 0:
1562 reg = ENCL_INFO_READ;
1563 break;
1564 case 1:
1565 reg = ENCI_INFO_READ;
1566 break;
1567 case 2:
1568 reg = ENCP_INFO_READ;
1569 break;
1570 case 3:
1571 reg = ENCT_INFO_READ;
1572 break;
1573 }
Googler9726be62022-12-14 05:53:31 +00001574 }
Googler9398cc32022-12-02 17:21:52 +08001575
1576 reg_val = osd_reg_read(reg + offset);
1577
1578 enc_line = (reg_val >> 16) & 0x1fff;
Googler9726be62022-12-14 05:53:31 +00001579
Googler4f18c0c2022-09-20 17:23:36 +08001580 return enc_line;
1581}
1582
Googler9726be62022-12-14 05:53:31 +00001583static int get_enter_encp_line(u32 viu_type)
Googler4f18c0c2022-09-20 17:23:36 +08001584{
1585 int enc_line = 0;
1586
Googler9726be62022-12-14 05:53:31 +00001587 enc_line = get_encp_line(viu_type);
Googler4f18c0c2022-09-20 17:23:36 +08001588 if (enc_line > vsync_enter_line_max)
1589 vsync_enter_line_max = enc_line;
1590 return enc_line;
1591}
1592
Googler9726be62022-12-14 05:53:31 +00001593static int get_exit_encp_line(u32 viu_type)
Googler4f18c0c2022-09-20 17:23:36 +08001594{
1595 int enc_line = 0;
1596
Googler9726be62022-12-14 05:53:31 +00001597 enc_line = get_encp_line(viu_type);
Googler4f18c0c2022-09-20 17:23:36 +08001598 if (enc_line > vsync_exit_line_max)
1599 vsync_exit_line_max = enc_line;
1600 return enc_line;
1601}
1602
1603static void osd_vpu_power_on(void)
1604{
1605#ifdef CONFIG_AMLOGIC_VPU
Googler9398cc32022-12-02 17:21:52 +08001606 struct vpu_dev_s *osd1_vpu_dev;
1607 struct vpu_dev_s *osd2_vpu_dev;
1608 struct vpu_dev_s *osd_scale_vpu_dev;
Googler0109c452022-10-13 17:50:39 +08001609
Googler9398cc32022-12-02 17:21:52 +08001610 osd1_vpu_dev = vpu_dev_register(VPU_VIU_OSD1, "OSD1");
1611 vpu_dev_mem_power_on(osd1_vpu_dev);
1612 osd2_vpu_dev = vpu_dev_register(VPU_VIU_OSD2, "OSD2");
1613 vpu_dev_mem_power_on(osd2_vpu_dev);
1614 osd_scale_vpu_dev =
1615 vpu_dev_register(VPU_VIU_OSD_SCALE, "OSD_SCALE");
1616 vpu_dev_mem_power_on(osd_scale_vpu_dev);
1617 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
1618 struct vpu_dev_s *osd2_scale_vpu_dev;
1619 struct vpu_dev_s *osd3_vpu_dev;
1620 struct vpu_dev_s *blend34_vpu_dev;
1621
1622 osd2_scale_vpu_dev =
1623 vpu_dev_register(VPU_VD2_OSD2_SCALE, "OSD2_SCALE");
1624 vpu_dev_mem_power_on(osd2_scale_vpu_dev);
1625 osd3_vpu_dev = vpu_dev_register(VPU_VIU_OSD3, "OSD3");
1626 vpu_dev_mem_power_on(osd3_vpu_dev);
1627 blend34_vpu_dev =
1628 vpu_dev_register(VPU_OSD_BLD34, "BLEND34_SCALE");
1629 vpu_dev_mem_power_on(blend34_vpu_dev);
Googler4f18c0c2022-09-20 17:23:36 +08001630 }
1631 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
Googler9398cc32022-12-02 17:21:52 +08001632 struct vpu_dev_s *meson_afbc_vpu_dev;
1633
1634 meson_afbc_vpu_dev =
1635 vpu_dev_register(VPU_AFBC_DEC, "MESON_AFBC");
1636 vpu_dev_mem_power_on(meson_afbc_vpu_dev);
Googler4f18c0c2022-09-20 17:23:36 +08001637 } else if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) {
Googler9398cc32022-12-02 17:21:52 +08001638 struct vpu_dev_s *mali_afbc_vpu_dev;
1639
1640 mali_afbc_vpu_dev =
1641 vpu_dev_register(VPU_MAIL_AFBCD, "MALI_AFBC");
1642 vpu_dev_mem_power_on(mali_afbc_vpu_dev);
Googler4f18c0c2022-09-20 17:23:36 +08001643 }
1644#endif
1645}
1646
1647static void osd_vpu_power_on_viu2(void)
1648{
1649#ifdef CONFIG_AMLOGIC_VPU
1650 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
Googler9398cc32022-12-02 17:21:52 +08001651 struct vpu_dev_s *viu2_osd1_vpu_dev;
1652 struct vpu_dev_s *viu2_ofifo_vpu_dev;
1653 struct vpu_dev_s *viu2_osd_rot_vpu_dev;
Googler4f18c0c2022-09-20 17:23:36 +08001654 u32 val;
1655
Googler9398cc32022-12-02 17:21:52 +08001656 viu2_osd1_vpu_dev =
1657 vpu_dev_register(VPU_VIU2_OSD1, "VIU2_OSD1");
1658 vpu_dev_mem_power_on(viu2_osd1_vpu_dev);
1659 viu2_ofifo_vpu_dev =
1660 vpu_dev_register(VPU_VIU2_OFIFO, "VIU2_OFIFO");
1661 vpu_dev_mem_power_on(viu2_ofifo_vpu_dev);
1662 viu2_osd_rot_vpu_dev =
1663 vpu_dev_register(VPU_VIU2_OSD_ROT, "VIU2_ROT");
1664 vpu_dev_mem_power_on(viu2_osd_rot_vpu_dev);
Googler4f18c0c2022-09-20 17:23:36 +08001665 val = osd_reg_read(VPU_CLK_GATE);
1666 val = val | 0x30000;
1667 osd_reg_write(VPU_CLK_GATE, val);
1668 }
1669#endif
1670}
1671
Googler9398cc32022-12-02 17:21:52 +08001672/* validate if osdx is routed to vpp_topx */
1673static int validate_osd(u32 osd_index, u32 viu_index)
1674{
1675 u32 ret = 0;
1676 u32 viu_osd_table = osd_hw.viu_osd_table[viu_index];
1677
1678 while ((viu_osd_table & 0xf) != 0xf) {
1679 if (osd_index == (viu_osd_table & 0xf)) {
1680 ret = 1;
1681 break;
1682 }
1683 viu_osd_table = viu_osd_table >> 4;
1684 }
1685
1686 return ret;
1687}
1688
Googler4f18c0c2022-09-20 17:23:36 +08001689u32 get_output_device_id(u32 index)
1690{
1691 u32 output_index = VIU1;
1692
Googler9398cc32022-12-02 17:21:52 +08001693 if (validate_osd(index, VIU1))
1694 output_index = VIU1;
1695 else if (validate_osd(index, VIU2))
1696 output_index = VIU2;
1697 else if (validate_osd(index, VIU3))
1698 output_index = VIU3;
1699 else
1700 osd_log_err("wrong osd index, %s, %d\n", __func__, __LINE__);
1701
Googler4f18c0c2022-09-20 17:23:36 +08001702 return output_index;
1703}
1704
1705static int get_osd_hwc_type(u32 index)
1706{
1707 int ret = 0;
1708 u32 output_index;
1709
1710 output_index = get_output_device_id(index);
1711 /* new hwcomposer enable */
1712 if (osd_hw.hwc_enable[output_index]) {
1713 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE)
1714 ret = OSD_G12A_NEW_HWC;
1715 else
1716 ret = OSD_OTHER_NEW_HWC;
Googler9398cc32022-12-02 17:21:52 +08001717 } else {
Googler4f18c0c2022-09-20 17:23:36 +08001718 ret = OSD_OLD_HWC;
Googler9398cc32022-12-02 17:21:52 +08001719 }
Googler4f18c0c2022-09-20 17:23:36 +08001720 return ret;
1721}
1722
1723#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
1724static inline int find_buf_num(u32 yres, u32 yoffset)
1725{
1726 int n = yres;
1727 int i;
1728
1729 for (i = 0; i < OSD_MAX_BUF_NUM; i++) {
1730 /* find current addr position. */
1731 if (yoffset < (n))
1732 break;
1733 n += yres;
1734 }
1735 return i;
1736}
1737
1738static void osd_toggle_buffer_single(struct kthread_work *work)
1739{
1740 struct osd_fence_map_s *data, *next;
1741 struct list_head saved_list;
1742
1743 mutex_lock(&post_fence_list_lock[VIU1]);
1744 saved_list = post_fence_list[VIU1];
1745 list_replace_init(&post_fence_list[VIU1], &saved_list);
1746 mutex_unlock(&post_fence_list_lock[VIU1]);
1747 list_for_each_entry_safe(data, next, &saved_list, list) {
1748 osd_pan_display_single_fence(data);
1749 list_del(&data->list);
1750 kfree(data);
1751 }
1752}
1753
1754static void osd_toggle_buffer_layers(struct kthread_work *work)
1755{
1756 struct osd_layers_fence_map_s *data, *next;
1757 struct list_head saved_list;
1758
1759 mutex_lock(&post_fence_list_lock[VIU1]);
1760 saved_list = post_fence_list[VIU1];
1761 list_replace_init(&post_fence_list[VIU1], &saved_list);
1762 mutex_unlock(&post_fence_list_lock[VIU1]);
1763 list_for_each_entry_safe(data, next, &saved_list, list) {
1764 osd_pan_display_layers_fence(data);
1765 list_del(&data->list);
1766 kfree(data);
1767 }
1768}
1769
Googler4f18c0c2022-09-20 17:23:36 +08001770static void osd_toggle_buffer(struct kthread_work *work)
1771{
1772 u32 hwc_enable;
1773
1774 hwc_enable = osd_hw.hwc_enable[VIU1];
1775 if (osd_hw.osd_fence[VIU1][hwc_enable].toggle_buffer_handler)
1776 osd_hw.osd_fence[VIU1][hwc_enable]
Googler9398cc32022-12-02 17:21:52 +08001777 .toggle_buffer_handler(work);
Googler4f18c0c2022-09-20 17:23:36 +08001778}
1779
1780static void osd_toggle_buffer_single_viu2(struct kthread_work *work)
1781{
1782 struct osd_fence_map_s *data, *next;
1783 struct list_head saved_list;
1784
1785 mutex_lock(&post_fence_list_lock[VIU2]);
1786 saved_list = post_fence_list[VIU2];
1787 list_replace_init(&post_fence_list[VIU2], &saved_list);
1788 mutex_unlock(&post_fence_list_lock[VIU2]);
1789 list_for_each_entry_safe(data, next, &saved_list, list) {
1790 osd_pan_display_single_fence_viu2(data);
1791 list_del(&data->list);
1792 kfree(data);
1793 }
1794}
1795
1796static void osd_toggle_buffer_layers_viu2(struct kthread_work *work)
1797{
1798 struct osd_layers_fence_map_s *data, *next;
1799 struct list_head saved_list;
1800
1801 mutex_lock(&post_fence_list_lock[VIU2]);
1802 saved_list = post_fence_list[VIU2];
1803 list_replace_init(&post_fence_list[VIU2], &saved_list);
1804 mutex_unlock(&post_fence_list_lock[VIU2]);
1805 list_for_each_entry_safe(data, next, &saved_list, list) {
1806 osd_pan_display_layers_fence_viu2(data);
1807 list_del(&data->list);
1808 kfree(data);
1809 }
1810}
1811
1812static void osd_toggle_buffer_viu2(struct kthread_work *work)
1813{
1814 u32 hwc_enable;
1815
1816 hwc_enable = osd_hw.hwc_enable[VIU2];
1817 if (osd_hw.osd_fence[VIU2][hwc_enable].toggle_buffer_handler)
1818 osd_hw.osd_fence[VIU2][hwc_enable]
1819 .toggle_buffer_handler(work);
1820}
1821
1822static int out_fence_create(u32 output_index, int *release_fence_fd)
1823{
1824 int out_fence_fd = -1;
Googler9726be62022-12-14 05:53:31 +00001825 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1};
1826 char toggle_thread_name[32] = {};
1827 unsigned long _cpu_mask = *cpumask_bits(&affinity_info.cpu_mask) & (~1);
Googler4f18c0c2022-09-20 17:23:36 +08001828
1829 if (!timeline_created[output_index]) {
1830 /* timeline has not been created */
1831 if (osd_timeline_create(output_index)) {
1832 kthread_init_worker
1833 (&buffer_toggle_worker[output_index]);
1834 sprintf(toggle_thread_name,
1835 "aml_buf_toggle_%d", output_index);
Googler9398cc32022-12-02 17:21:52 +08001836 buffer_toggle_thread[output_index] = kthread_run
1837 (kthread_worker_fn,
1838 &buffer_toggle_worker[output_index],
1839 toggle_thread_name);
Googler4f18c0c2022-09-20 17:23:36 +08001840 if (IS_ERR(buffer_toggle_thread[output_index])) {
1841 osd_log_err("create osd toggle kthread failed");
1842 return -1;
1843 }
1844 sched_setscheduler(buffer_toggle_thread[output_index],
1845 SCHED_FIFO, &param);
1846 if (output_index == VIU1)
Googler9398cc32022-12-02 17:21:52 +08001847 kthread_init_work
1848 (&buffer_toggle_work[output_index],
1849 osd_toggle_buffer);
Googler4f18c0c2022-09-20 17:23:36 +08001850 else if (output_index == VIU2)
Googler9398cc32022-12-02 17:21:52 +08001851 kthread_init_work
1852 (&buffer_toggle_work[output_index],
1853 osd_toggle_buffer_viu2);
Googler9726be62022-12-14 05:53:31 +00001854 /* set cpu affinity mask 0xe(work on cpu1~3) */
1855 set_cpus_allowed_ptr(buffer_toggle_thread[output_index],
1856 (struct cpumask *)&_cpu_mask);
Googler4f18c0c2022-09-20 17:23:36 +08001857 timeline_created[output_index] = 1;
1858 }
1859 }
1860
1861 /* hwc_enable disable create fence every time */
1862 if (!osd_hw.hwc_enable[output_index]) {
1863 out_fence_fd = osd_timeline_create_fence(output_index);
1864 if (out_fence_fd < 0) {
1865 osd_log_err("fence obj create fail\n");
1866 out_fence_fd = -1;
1867 }
1868 } else {
1869 /* hwc_enable enable create fence
1870 * when first sync request called
1871 */
1872 if (osd_hw.out_fence_fd[output_index] == -1) {
1873 out_fence_fd = osd_timeline_create_fence(output_index);
1874 if (out_fence_fd < 0) {
1875 osd_log_err("fence obj create fail\n");
1876 out_fence_fd = -1;
1877 }
1878 osd_hw.out_fence_fd[output_index] = out_fence_fd;
1879 } else {
1880 out_fence_fd = osd_hw.out_fence_fd[output_index];
1881 }
1882 }
1883 if (release_fence_fd)
1884 *release_fence_fd = out_fence_fd;
1885 return out_fence_fd;
1886}
1887
1888int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request)
1889{
1890 int out_fence_fd = -1;
1891 int buf_num = 0;
1892 int in_fence_fd = -1;
1893 u32 output_index = 0;
1894 struct osd_fence_map_s *fence_map =
1895 kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL);
1896
1897 output_index = get_output_device_id(index);
1898 osd_hw.hwc_enable[output_index] = 0;
1899 if (request->sync_req.magic == FB_SYNC_REQUEST_MAGIC) {
1900 buf_num = find_buf_num(yres, request->sync_req.yoffset);
1901 if (!fence_map) {
1902 osd_log_err("could not allocate osd_fence_map\n");
1903 return -ENOMEM;
1904 }
1905 mutex_lock(&post_fence_list_lock[output_index]);
1906 fence_map->op = 0xffffffff;
1907 fence_map->fb_index = index;
1908 fence_map->buf_num = buf_num;
1909 fence_map->yoffset = request->sync_req.yoffset;
1910 fence_map->xoffset = request->sync_req.xoffset;
1911 fence_map->yres = yres;
1912 fence_map->format = request->sync_req.format;
1913 fence_map->in_fd = request->sync_req.in_fen_fd;
1914 in_fence_fd = request->sync_req.in_fen_fd;
1915 osd_tprintk("request fence fd:%d\n", fence_map->in_fd);
Googler9398cc32022-12-02 17:21:52 +08001916 fence_map->in_fence = osd_get_fenceobj
1917 (request->sync_req.in_fen_fd);
Googler4f18c0c2022-09-20 17:23:36 +08001918 fence_map->out_fd =
1919 out_fence_create(output_index, &out_fence_fd);
1920 } else {
1921 buf_num = find_buf_num(yres, request->sync_req_old.yoffset);
1922 if (!fence_map) {
1923 osd_log_err("could not allocate osd_fence_map\n");
1924 return -ENOMEM;
1925 }
1926 mutex_lock(&post_fence_list_lock[output_index]);
1927 fence_map->op = 0xffffffff;
1928 fence_map->fb_index = index;
1929 fence_map->buf_num = buf_num;
1930 fence_map->yoffset = request->sync_req_old.yoffset;
1931 fence_map->xoffset = request->sync_req_old.xoffset;
1932 fence_map->yres = yres;
1933 fence_map->in_fd = request->sync_req_old.in_fen_fd;
1934 in_fence_fd = request->sync_req_old.in_fen_fd;
1935 osd_tprintk("request fence fd:%d\n", fence_map->in_fd);
Googler9398cc32022-12-02 17:21:52 +08001936 fence_map->in_fence = osd_get_fenceobj
1937 (request->sync_req_old.in_fen_fd);
Googler4f18c0c2022-09-20 17:23:36 +08001938 fence_map->out_fd =
1939 out_fence_create(output_index, &out_fence_fd);
1940 }
1941 list_add_tail(&fence_map->list, &post_fence_list[output_index]);
1942 mutex_unlock(&post_fence_list_lock[output_index]);
1943 kthread_queue_work(&buffer_toggle_worker[output_index],
1944 &buffer_toggle_work[output_index]);
1945 if (in_fence_fd >= 0)
1946 __close_fd(current->files, in_fence_fd);
1947 return out_fence_fd;
1948}
1949
Googler4f18c0c2022-09-20 17:23:36 +08001950static int sync_render_single_fence(u32 index, u32 yres,
Googler9398cc32022-12-02 17:21:52 +08001951 struct sync_req_render_s *request,
1952 ulong phys_addr,
1953 size_t len)
Googler4f18c0c2022-09-20 17:23:36 +08001954{
1955 int out_fence_fd = -1;
1956 int buf_num = 0;
1957 u32 xoffset, yoffset;
1958 u32 output_index = 0;
1959 struct osd_fence_map_s *fence_map = NULL;
1960
1961 if (index > OSD1)
1962 return -1;
1963 xoffset = request->xoffset;
1964 yoffset = request->yoffset;
1965 buf_num = find_buf_num(yres, yoffset);
Googler9398cc32022-12-02 17:21:52 +08001966 fence_map = kzalloc(sizeof(*fence_map), GFP_KERNEL);
Googler4f18c0c2022-09-20 17:23:36 +08001967 if (!fence_map) {
1968 osd_log_err("could not allocate osd_fence_map\n");
1969 return -ENOMEM;
1970 }
1971 output_index = get_output_device_id(index);
1972 mutex_lock(&post_fence_list_lock[output_index]);
1973 fence_map->op = 0xffffffff;
1974 fence_map->fb_index = index;
1975 fence_map->buf_num = buf_num;
1976 fence_map->yoffset = yoffset;
1977 fence_map->xoffset = xoffset;
1978 fence_map->yres = yres;
1979 fence_map->in_fd = request->in_fen_fd;
1980 fence_map->ext_addr = phys_addr;
1981 if (fence_map->ext_addr) {
1982 fence_map->width = request->width;
1983 fence_map->height = request->height;
1984 fence_map->dst_x = request->dst_x;
1985 fence_map->dst_y = request->dst_y;
1986 fence_map->dst_w = request->dst_w;
1987 fence_map->dst_h = request->dst_h;
1988 fence_map->byte_stride = request->byte_stride;
1989 fence_map->pxiel_stride = request->pxiel_stride;
1990 fence_map->afbc_inter_format = request->afbc_inter_format;
1991 fence_map->afbc_len = len;
1992 }
1993 fence_map->format = request->format;
1994 fence_map->compose_type = request->type;
1995 fence_map->op = request->op;
1996
1997 osd_tprintk("direct render fence fd:%d\n", fence_map->in_fd);
1998 fence_map->in_fence = osd_get_fenceobj(fence_map->in_fd);
1999 fence_map->out_fd =
2000 out_fence_create(output_index, &out_fence_fd);
2001 /* Todo: */
2002 list_add_tail(&fence_map->list, &post_fence_list[output_index]);
2003 mutex_unlock(&post_fence_list_lock[output_index]);
2004 kthread_queue_work(&buffer_toggle_worker[output_index],
2005 &buffer_toggle_work[output_index]);
2006 request->out_fen_fd = out_fence_fd;
2007 if (request->in_fen_fd >= 0)
2008 __close_fd(current->files, request->in_fen_fd);
2009 return out_fence_fd;
2010}
2011
2012static int sync_render_layers_fence(u32 index, u32 yres,
Googler9398cc32022-12-02 17:21:52 +08002013 struct sync_req_render_s *request,
2014 ulong phys_addr,
2015 size_t len)
Googler4f18c0c2022-09-20 17:23:36 +08002016{
2017 int out_fence_fd = -1;
2018 s32 in_fence_fd;
2019 u32 output_index = 0;
2020 struct osd_layers_fence_map_s *fence_map = NULL;
2021
Googler9398cc32022-12-02 17:21:52 +08002022 if (index >= OSD_MAX)
Googler4f18c0c2022-09-20 17:23:36 +08002023 return -1;
2024 output_index = get_output_device_id(index);
2025 in_fence_fd = request->in_fen_fd;
2026 mutex_lock(&post_fence_list_lock[output_index]);
2027 fence_map = &map_layers[output_index];
2028 fence_map->cmd = LAYER_SYNC;
2029 fence_map->layer_map[index].fb_index = index;
2030 /* layer_map[index].enable will update if have blank ioctl */
2031 fence_map->layer_map[index].enable = request->op;
2032 fence_map->layer_map[index].in_fd = request->in_fen_fd;
2033 if (request->shared_fd < 0)
2034 fence_map->layer_map[index].buf_file = NULL;
2035 else
2036 fence_map->layer_map[index].buf_file = fget(request->shared_fd);
2037 fence_map->layer_map[index].ext_addr = phys_addr;
2038 fence_map->layer_map[index].format = request->format;
2039 fence_map->layer_map[index].compose_type = request->type;
2040 fence_map->layer_map[index].fb_width = request->fb_width;
2041 fence_map->layer_map[index].fb_height = request->fb_height;
2042 fence_map->layer_map[index].src_x = request->xoffset;
2043 fence_map->layer_map[index].src_y = request->yoffset;
2044 fence_map->layer_map[index].src_w = request->width;
2045 fence_map->layer_map[index].src_h = request->height;
2046 fence_map->layer_map[index].dst_x = request->dst_x;
2047 fence_map->layer_map[index].dst_y = request->dst_y;
2048 fence_map->layer_map[index].dst_w = request->dst_w;
2049 fence_map->layer_map[index].dst_h = request->dst_h;
2050 fence_map->layer_map[index].byte_stride =
2051 request->byte_stride;
2052 fence_map->layer_map[index].pxiel_stride =
2053 request->pxiel_stride;
2054 fence_map->layer_map[index].afbc_inter_format =
2055 request->afbc_inter_format;
2056 fence_map->layer_map[index].zorder = request->zorder;
2057 fence_map->layer_map[index].blend_mode =
2058 request->blend_mode;
2059 fence_map->layer_map[index].plane_alpha =
2060 request->plane_alpha;
2061 fence_map->layer_map[index].dim_layer = request->dim_layer;
2062 fence_map->layer_map[index].dim_color = request->dim_color;
2063 fence_map->layer_map[index].afbc_len = len;
Googler9726be62022-12-14 05:53:31 +00002064 fence_map->layer_map[index].secure_enable = request->secure_enable;
Googler4f18c0c2022-09-20 17:23:36 +08002065 /* just return out_fd,but not signal */
2066 /* no longer put list, will put them via do_hwc */
2067 fence_map->layer_map[index].in_fence = osd_get_fenceobj(in_fence_fd);
2068 fence_map->layer_map[index].out_fd =
2069 out_fence_create(output_index, &out_fence_fd);
2070 mutex_unlock(&post_fence_list_lock[output_index]);
Googler9398cc32022-12-02 17:21:52 +08002071 osd_log_dbg(MODULE_FENCE, "%s:osd%d: ind_fd=%d,out_fd=%d\n",
2072 __func__,
2073 fence_map->layer_map[index].fb_index,
2074 fence_map->layer_map[index].in_fd,
2075 fence_map->layer_map[index].out_fd);
Googler4f18c0c2022-09-20 17:23:36 +08002076 request->out_fen_fd = out_fence_fd;
2077 if (in_fence_fd >= 0)
2078 __close_fd(current->files, in_fence_fd);
2079 if (request->shared_fd >= 0)
2080 __close_fd(current->files, request->shared_fd);
2081 return out_fence_fd;
2082}
2083
2084int osd_sync_request_render(u32 index, u32 yres,
Googler9398cc32022-12-02 17:21:52 +08002085 struct sync_req_render_s *request,
2086 ulong phys_addr,
2087 size_t len)
Googler4f18c0c2022-09-20 17:23:36 +08002088{
2089 int line, hwc_enable;
2090 u32 output_index = 0;
2091
Googler9726be62022-12-14 05:53:31 +00002092 line = get_encp_line(output_index);
Googler4f18c0c2022-09-20 17:23:36 +08002093 output_index = get_output_device_id(index);
2094 osd_log_dbg2(MODULE_RENDER,
Googler9398cc32022-12-02 17:21:52 +08002095 "enter %s,encp line=%d\n",
2096 __func__, line);
Googler4f18c0c2022-09-20 17:23:36 +08002097 if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V1)
2098 osd_hw.hwc_enable[output_index] = 0;
2099 else if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V2)
2100 osd_hw.hwc_enable[output_index] = 1;
2101 output_index = get_output_device_id(index);
2102 hwc_enable = osd_hw.hwc_enable[output_index];
2103
2104 if (osd_hw.osd_fence[output_index][hwc_enable].sync_fence_handler)
2105 osd_hw.osd_fence[output_index][hwc_enable]
2106 .sync_fence_handler(index, yres,
2107 request, phys_addr, len);
2108 return request->out_fen_fd;
2109}
2110
2111int osd_sync_do_hwc(u32 index, struct do_hwc_cmd_s *hwc_cmd)
2112{
2113 int out_fence_fd = -1;
2114 struct osd_layers_fence_map_s *fence_map = NULL;
2115 int line;
2116 u32 output_index = 0;
2117
2118 output_index = get_output_device_id(index);
Googler9726be62022-12-14 05:53:31 +00002119 line = get_encp_line(output_index);
Googler4f18c0c2022-09-20 17:23:36 +08002120 osd_log_dbg2(MODULE_RENDER,
Googler9398cc32022-12-02 17:21:52 +08002121 "enter %s,encp line=%d\n",
2122 __func__, line);
2123 fence_map = kzalloc(sizeof(*fence_map), GFP_KERNEL);
Googler4f18c0c2022-09-20 17:23:36 +08002124 if (!fence_map)
2125 return -ENOMEM;
2126 osd_hw.hwc_enable[output_index] = 1;
2127 mutex_lock(&post_fence_list_lock[output_index]);
2128 memcpy(fence_map, &map_layers[output_index],
2129 sizeof(struct osd_layers_fence_map_s));
2130 /* clear map_layers, need alloc next add_sync ioctl */
2131 memset(&map_layers[output_index], 0,
2132 sizeof(struct osd_layers_fence_map_s));
2133 fence_map->out_fd =
2134 out_fence_create(output_index, &out_fence_fd);
2135 fence_map->disp_info.background_w =
2136 hwc_cmd->disp_info.background_w;
2137 fence_map->disp_info.background_h =
2138 hwc_cmd->disp_info.background_h;
2139 fence_map->disp_info.fullscreen_w =
2140 hwc_cmd->disp_info.fullscreen_w;
2141 fence_map->disp_info.fullscreen_h =
2142 hwc_cmd->disp_info.fullscreen_h;
2143 fence_map->disp_info.position_x =
2144 hwc_cmd->disp_info.position_x;
2145 fence_map->disp_info.position_y =
2146 hwc_cmd->disp_info.position_y;
2147 fence_map->disp_info.position_w =
2148 hwc_cmd->disp_info.position_w;
2149 fence_map->disp_info.position_h =
2150 hwc_cmd->disp_info.position_h;
2151 fence_map->hdr_mode = hwc_cmd->hdr_mode;
2152 /* other info set via add_sync and blank ioctl */
2153 list_add_tail(&fence_map->list, &post_fence_list[output_index]);
2154 /* after do_hwc, clear osd_hw.out_fence_fd */
2155 if (timeline_created[output_index] &&
2156 osd_hw.out_fence_fd[output_index])
2157 osd_hw.out_fence_fd[output_index] = -1;
2158 mutex_unlock(&post_fence_list_lock[output_index]);
2159 kthread_queue_work(&buffer_toggle_worker[output_index],
2160 &buffer_toggle_work[output_index]);
2161 if (get_logo_loaded()) {
2162 int logo_index;
2163
2164 logo_index = osd_get_logo_index();
2165 if (logo_index < 0) {
2166 osd_log_info("set logo loaded\n");
2167 set_logo_loaded();
2168 }
2169 }
Googler9398cc32022-12-02 17:21:52 +08002170 osd_log_dbg(MODULE_FENCE, "%s :out_fence_fd=%d\n",
2171 __func__, out_fence_fd);
Googler4f18c0c2022-09-20 17:23:36 +08002172 return out_fence_fd;
2173}
2174
2175static int osd_wait_buf_ready(struct osd_fence_map_s *fence_map)
2176{
2177 s32 ret = -1;
Googler9398cc32022-12-02 17:21:52 +08002178 struct dma_fence *buf_ready_fence = NULL;
Googler4f18c0c2022-09-20 17:23:36 +08002179
2180 if (fence_map->in_fd <= 0)
2181 return -1;
2182 buf_ready_fence = fence_map->in_fence;
Googler9398cc32022-12-02 17:21:52 +08002183 if (!buf_ready_fence)
Googler4f18c0c2022-09-20 17:23:36 +08002184 return -1;/* no fence ,output directly. */
2185 ret = osd_wait_fenceobj(buf_ready_fence, 4000);
2186 if (ret < 0) {
2187 osd_log_err("Sync Fence wait error:%d\n", ret);
2188 osd_log_err("-----wait buf idx:[%d] ERROR\n"
Googler9398cc32022-12-02 17:21:52 +08002189 "-----on screen buf idx:[%d]\n",
2190 fence_map->buf_num, find_buf_num(fence_map->yres,
2191 osd_hw.pandata[fence_map->fb_index].y_start));
2192 } else {
Googler4f18c0c2022-09-20 17:23:36 +08002193 ret = 1;
Googler9398cc32022-12-02 17:21:52 +08002194 }
Googler4f18c0c2022-09-20 17:23:36 +08002195 return ret;
2196}
2197
2198static int osd_wait_buf_ready_combine(struct layer_fence_map_s *layer_map)
2199{
2200 s32 ret = -1;
Googler9398cc32022-12-02 17:21:52 +08002201 struct dma_fence *buf_ready_fence = NULL;
Googler4f18c0c2022-09-20 17:23:36 +08002202
2203 if (layer_map->in_fd <= 0)
2204 return -1;
2205 buf_ready_fence = layer_map->in_fence;
Googler9398cc32022-12-02 17:21:52 +08002206 if (!buf_ready_fence)
Googler9726be62022-12-14 05:53:31 +00002207 return -1;/* no fence ,output directly. */
Googler9398cc32022-12-02 17:21:52 +08002208
Googler4f18c0c2022-09-20 17:23:36 +08002209 ret = osd_wait_fenceobj(buf_ready_fence, 4000);
2210 if (ret < 0)
2211 osd_log_err("osd%d: Sync Fence wait error:%d\n",
Googler9398cc32022-12-02 17:21:52 +08002212 layer_map->fb_index, ret);
Googler4f18c0c2022-09-20 17:23:36 +08002213 else
2214 ret = 1;
2215
Googler9398cc32022-12-02 17:21:52 +08002216 osd_log_dbg(MODULE_FENCE, "%s:osd%d,in_fd=%d\n",
2217 __func__, layer_map->fb_index, layer_map->in_fd);
Googler4f18c0c2022-09-20 17:23:36 +08002218 return ret;
2219}
2220
2221#else
2222int osd_sync_request(u32 index, u32 yres, struct fb_sync_request_s *request)
2223{
Googler9398cc32022-12-02 17:21:52 +08002224 osd_log_err("%s not supported\n", __func__);
Googler4f18c0c2022-09-20 17:23:36 +08002225 return -5566;
2226}
2227
Googler4f18c0c2022-09-20 17:23:36 +08002228int osd_sync_request_render(u32 index, u32 yres,
Googler9398cc32022-12-02 17:21:52 +08002229 struct sync_req_render_s *request,
2230 ulong phys_addr,
2231 size_t len)
Googler4f18c0c2022-09-20 17:23:36 +08002232{
Googler9398cc32022-12-02 17:21:52 +08002233 osd_log_err("%s not supported\n", __func__);
Googler4f18c0c2022-09-20 17:23:36 +08002234 return -5566;
2235}
2236
Googler9398cc32022-12-02 17:21:52 +08002237int osd_sync_do_hwc(u32 index, struct do_hwc_cmd_s *hwc_cmd)
Googler4f18c0c2022-09-20 17:23:36 +08002238{
Googler9398cc32022-12-02 17:21:52 +08002239 osd_log_err("%s not supported\n", __func__);
Googler4f18c0c2022-09-20 17:23:36 +08002240 return -5566;
2241}
2242#endif
Googler9726be62022-12-14 05:53:31 +00002243static void osd_get_max_window_size(struct dispdata_s *dst_data)
2244{
2245 int i;
2246
2247 memset(dst_data, 0x0, sizeof(struct dispdata_s));
2248 for (i = 0; i < osd_hw.osd_meson_dev.viu1_osd_count; i++) {
2249 if (osd_hw.enable[i]) {
2250 if (dst_data->x > osd_hw.dst_data[i].x)
2251 dst_data->x = osd_hw.dst_data[i].x;
2252 if (dst_data->y > osd_hw.dst_data[i].y)
2253 dst_data->y = osd_hw.dst_data[i].y;
2254 if (dst_data->w < osd_hw.dst_data[i].w)
2255 dst_data->w = osd_hw.dst_data[i].w;
2256 if (dst_data->h < osd_hw.dst_data[i].h)
2257 dst_data->h = osd_hw.dst_data[i].h;
2258 }
2259 }
2260 osd_log_dbg(MODULE_BLEND, "max window size:%d, %d,%d,%d\n",
2261 dst_data->x, dst_data->y, dst_data->w, dst_data->h);
2262}
2263
2264static void osd_get_max_fb_size(struct dispdata_s *src_data)
2265{
2266 int i;
2267
2268 memset(src_data, 0x0, sizeof(struct dispdata_s));
2269 for (i = 0; i < osd_hw.osd_meson_dev.viu1_osd_count; i++) {
2270 if (src_data->x > osd_hw.src_data[i].x)
2271 src_data->x = osd_hw.src_data[i].x;
2272 if (src_data->y > osd_hw.src_data[i].y)
2273 src_data->y = osd_hw.src_data[i].y;
2274 if (src_data->w < osd_hw.src_data[i].w)
2275 src_data->w = osd_hw.src_data[i].w;
2276 if (src_data->h < osd_hw.src_data[i].h)
2277 src_data->h = osd_hw.src_data[i].h;
2278 }
2279 osd_log_dbg(MODULE_BLEND, "max fb size:%d, %d,%d,%d\n",
2280 src_data->x, src_data->y, src_data->w, src_data->h);
2281}
2282
2283static void osd_update_disp_dst_size(u32 index)
2284{
2285 u32 output_index;
2286
2287 output_index = get_output_device_id(index);
2288 if (osd_hw.hwc_enable[output_index] &&
2289 osd_hw.osd_display_fb[output_index]) {
2290 struct display_flip_info_s disp_info;
2291 struct dispdata_s dst_data;
2292
2293 osd_get_background_size(index, &disp_info);
2294 osd_get_max_window_size(&dst_data);
2295 disp_info.position_x = dst_data.x;
2296 disp_info.position_y = dst_data.y;
2297 disp_info.position_w = dst_data.w;
2298 disp_info.position_h = dst_data.h;
2299 osd_set_background_size(index, &disp_info);
2300 }
2301}
2302
2303static void osd_update_disp_src_size(u32 index)
2304{
2305 u32 output_index;
2306
2307 output_index = get_output_device_id(index);
2308 if (osd_hw.hwc_enable[output_index] &&
2309 osd_hw.osd_display_fb[output_index]) {
2310 struct display_flip_info_s disp_info;
2311 struct dispdata_s fb_data;
2312
2313 osd_get_background_size(index, &disp_info);
2314 osd_get_max_fb_size(&fb_data);
2315 disp_info.background_w = fb_data.w;
2316 disp_info.background_h = fb_data.h;
2317 osd_set_background_size(index, &disp_info);
2318 }
2319}
2320
Googler4f18c0c2022-09-20 17:23:36 +08002321void osd_set_enable_hw(u32 index, u32 enable)
2322{
2323 u32 output_index = 0;
2324
2325 output_index = get_output_device_id(index);
2326 if (osd_hw.hwc_enable[output_index]) {
Googler9398cc32022-12-02 17:21:52 +08002327 if (index >= OSD_MAX)
Googler4f18c0c2022-09-20 17:23:36 +08002328 return;
Googler9398cc32022-12-02 17:21:52 +08002329 if (osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE &&
2330 index == OSD2) {
Googler4f18c0c2022-09-20 17:23:36 +08002331 osd_enable_hw(index, enable);
Googler9398cc32022-12-02 17:21:52 +08002332 } else {
Googler4f18c0c2022-09-20 17:23:36 +08002333#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
2334 mutex_lock(&post_fence_list_lock[output_index]);
Googler9398cc32022-12-02 17:21:52 +08002335 map_layers[output_index]
2336 .layer_map[index].fb_index = index;
2337 map_layers[output_index]
2338 .layer_map[index].enable = enable;
Googler4f18c0c2022-09-20 17:23:36 +08002339 map_layers[output_index].cmd = BLANK_CMD;
2340 mutex_unlock(&post_fence_list_lock[output_index]);
Googler9398cc32022-12-02 17:21:52 +08002341 osd_log_dbg(MODULE_BASE, "%s: osd%d,enable=%d\n",
2342 __func__, index, enable);
Googler4f18c0c2022-09-20 17:23:36 +08002343#endif
2344 }
Googler9398cc32022-12-02 17:21:52 +08002345 } else {
Googler4f18c0c2022-09-20 17:23:36 +08002346 osd_enable_hw(index, enable);
Googler9398cc32022-12-02 17:21:52 +08002347 }
Googler4f18c0c2022-09-20 17:23:36 +08002348}
2349
2350void osd_update_3d_mode(void)
2351{
2352 int i = 0;
2353
2354 /* only called by vsync irq or rdma irq */
2355 for (i = 0; i <= OSD2; i++)
2356 if (osd_hw.mode_3d[i].enable)
2357 osd_update_disp_3d_mode(i);
2358}
2359
2360static inline void wait_vsync_wakeup(void)
2361{
Googler4f18c0c2022-09-20 17:23:36 +08002362 wake_up_interruptible_all(&osd_vsync_wq);
2363}
2364
Googler9726be62022-12-14 05:53:31 +00002365static inline void wait_vsync_wakeup_viu2(void)
2366{
Googler9726be62022-12-14 05:53:31 +00002367 wake_up_interruptible_all(&osd_vsync2_wq);
2368}
2369
Googler9398cc32022-12-02 17:21:52 +08002370static inline void wait_vsync_wakeup_viu3(void)
2371{
2372 wake_up_interruptible_all(&osd_vsync3_wq);
2373}
2374
2375static inline void wait_rdma_done_wakeup(void)
2376{
2377 vsync_hit[VIU1] = true;
2378 wake_up_interruptible_all(&osd_rdma_vpp0_done_wq);
2379}
2380
2381static inline void wait_rdma_done_wakeup_viu2(void)
2382{
2383 vsync_hit[VIU2] = true;
2384 wake_up_interruptible_all(&osd_rdma_vpp1_done_wq);
2385}
2386
2387static inline void wait_rdma_done_wakeup_viu3(void)
2388{
2389 vsync_hit[VIU3] = true;
2390 wake_up_interruptible_all(&osd_rdma_vpp2_done_wq);
2391}
2392
Googler9726be62022-12-14 05:53:31 +00002393static s64 get_adjust_vsynctime(u32 output_index)
2394{
2395 struct vinfo_s *vinfo = NULL;
2396 int line, active_begin_line;
2397 int vinfo_height;
2398 int thresh_line, vsync_time;
2399 s64 adjust_nsec;
2400
2401 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08002402 if (vinfo && vinfo->name && (!strcmp(vinfo->name, "invalid") ||
Googler9726be62022-12-14 05:53:31 +00002403 !strcmp(vinfo->name, "null"))) {
Googler9398cc32022-12-02 17:21:52 +08002404 active_begin_line = get_active_begin_line(output_index);
2405 line = get_enter_encp_line(output_index);
Googler9726be62022-12-14 05:53:31 +00002406 /* if nearly vsync signal, wait vsync here */
2407 vinfo_height = osd_hw.field_out_en[output_index] ?
2408 (osd_hw.vinfo_height[output_index] * 2) :
2409 osd_hw.vinfo_height[output_index];
2410 thresh_line = vsync_threshold;
2411 if (line > thresh_line) {
2412 vsync_time = 1000000 * vinfo->sync_duration_den /
2413 vinfo->sync_duration_num;
2414 adjust_nsec = div_u64((u64)vsync_time *
2415 (line - thresh_line),
2416 (vinfo_height +
2417 active_begin_line)) * 1000;
2418 vsync_adjust_hit++;
2419 return adjust_nsec;
2420
2421 } else {
2422 return 0;
2423 }
2424 } else {
2425 return 0;
2426 }
2427}
2428
2429void osd_update_vsync_timestamp(void)
Googler38bda472022-08-19 10:07:08 -07002430{
Googler0109c452022-10-13 17:50:39 +08002431 ktime_t stime;
Googler9398cc32022-12-02 17:21:52 +08002432 s64 cur_timestamp;
Googler4f18c0c2022-09-20 17:23:36 +08002433
Googler0109c452022-10-13 17:50:39 +08002434 stime = ktime_get();
Googler9398cc32022-12-02 17:21:52 +08002435 cur_timestamp = stime - get_adjust_vsynctime(VIU1);
2436 if (osd_log_level) {
2437 const struct vinfo_s *vinfo;
2438 s64 vsync_time, diff_time;
2439
2440 vinfo = get_current_vinfo();
2441 if (vinfo) {
2442 diff_time = cur_timestamp - timestamp[VIU1];
2443 vsync_time = div_s64((s64)vinfo->sync_duration_den * (s64)1000000000,
2444 (s64)vinfo->sync_duration_num);
2445 if (diff_time > (vsync_time + 1000000) ||
2446 diff_time < (vsync_time - 1000000))
2447 pr_info("vsync timestamp warning: cur=%lld, pre=%lld, diff_time=%lld\n",
2448 cur_timestamp, timestamp[VIU1], diff_time);
2449 }
2450 }
2451 timestamp[VIU1] = cur_timestamp;
2452 wait_vsync_wakeup();
Googler9726be62022-12-14 05:53:31 +00002453}
2454
2455void osd_update_vsync_timestamp_viu2(void)
2456{
2457 ktime_t stime;
2458
2459 stime = ktime_get();
Googler9398cc32022-12-02 17:21:52 +08002460 timestamp[VIU2] = stime - get_adjust_vsynctime(VIU2);
2461 wait_vsync_wakeup_viu2();
2462}
2463
2464void osd_update_vsync_timestamp_viu3(void)
2465{
2466 ktime_t stime;
2467
2468 stime = ktime_get();
2469 timestamp[VIU3] = stime - get_adjust_vsynctime(VIU3);
2470 wait_vsync_wakeup_viu3();
Googler9726be62022-12-14 05:53:31 +00002471}
2472
2473void osd_update_vsync_hit(void)
2474{
Googler4f18c0c2022-09-20 17:23:36 +08002475#ifdef FIQ_VSYNC
Googler9726be62022-12-14 05:53:31 +00002476 fiq_bridge_pulse_trigger(&osd_hw.fiq_handle_item);
Googler4f18c0c2022-09-20 17:23:36 +08002477#else
Googler9398cc32022-12-02 17:21:52 +08002478 wait_rdma_done_wakeup();
Googler9726be62022-12-14 05:53:31 +00002479#endif
2480}
2481
2482void osd_update_vsync_hit_viu2(void)
2483{
2484#ifdef FIQ_VSYNC
2485 fiq_bridge_pulse_trigger(&osd_hw.fiq_handle_item);
2486#else
Googler9398cc32022-12-02 17:21:52 +08002487 wait_rdma_done_wakeup_viu2();
2488#endif
2489}
2490
2491void osd_update_vsync_hit_viu3(void)
2492{
2493#ifdef FIQ_VSYNC
2494 fiq_bridge_pulse_trigger(&osd_hw.fiq_handle_item);
2495#else
2496 wait_rdma_done_wakeup_viu3();
Googler4f18c0c2022-09-20 17:23:36 +08002497#endif
2498}
2499
2500/* the return stride unit is 128bit(16bytes) */
Googler9398cc32022-12-02 17:21:52 +08002501static u32 line_stride_calc(u32 fmt_mode,
2502 u32 hsize,
2503 u32 stride_align_32bytes)
Googler4f18c0c2022-09-20 17:23:36 +08002504{
2505 u32 line_stride = 0;
Googler9398cc32022-12-02 17:21:52 +08002506 u32 line_stride_32bytes;
2507 u32 line_stride_64bytes;
Googler4f18c0c2022-09-20 17:23:36 +08002508
2509 switch (fmt_mode) {
2510 /* 2-bit LUT */
2511 case COLOR_INDEX_02_PAL4:
Googler9398cc32022-12-02 17:21:52 +08002512 line_stride = ((hsize << 1) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002513 break;
2514 /* 4-bit LUT */
2515 case COLOR_INDEX_04_PAL16:
Googler9398cc32022-12-02 17:21:52 +08002516 line_stride = ((hsize << 2) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002517 break;
2518 /* 8-bit LUT */
2519 case COLOR_INDEX_08_PAL256:
Googler9398cc32022-12-02 17:21:52 +08002520 line_stride = ((hsize << 3) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002521 break;
2522 /* 4:2:2, 32-bit per 2 pixels */
2523 case COLOR_INDEX_YUV_422:
Googler9398cc32022-12-02 17:21:52 +08002524 line_stride = ((((hsize + 1) >> 1) << 5) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002525 break;
2526 /* 16-bit LUT */
2527 case COLOR_INDEX_16_655:
2528 case COLOR_INDEX_16_844:
2529 case COLOR_INDEX_16_6442:
2530 case COLOR_INDEX_16_4444_R:
2531 case COLOR_INDEX_16_4642_R:
2532 case COLOR_INDEX_16_1555_A:
2533 case COLOR_INDEX_16_4444_A:
2534 case COLOR_INDEX_16_565:
Googler9398cc32022-12-02 17:21:52 +08002535 line_stride = ((hsize << 4) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002536 break;
2537 /* 32-bit LUT */
2538 case COLOR_INDEX_32_BGRX:
2539 case COLOR_INDEX_32_XBGR:
2540 case COLOR_INDEX_32_RGBX:
2541 case COLOR_INDEX_32_XRGB:
2542 case COLOR_INDEX_32_BGRA:
2543 case COLOR_INDEX_32_ABGR:
2544 case COLOR_INDEX_32_RGBA:
2545 case COLOR_INDEX_32_ARGB:
Googler9398cc32022-12-02 17:21:52 +08002546 line_stride = ((hsize << 5) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002547 break;
2548 /* 24-bit LUT */
2549 case COLOR_INDEX_24_6666_A:
2550 case COLOR_INDEX_24_6666_R:
2551 case COLOR_INDEX_24_8565:
2552 case COLOR_INDEX_24_5658:
2553 case COLOR_INDEX_24_888_B:
2554 case COLOR_INDEX_24_RGB:
Googler9398cc32022-12-02 17:21:52 +08002555 line_stride = ((hsize << 4) + (hsize << 3) + 127) >> 7;
Googler4f18c0c2022-09-20 17:23:36 +08002556 break;
2557 }
Googler9398cc32022-12-02 17:21:52 +08002558 line_stride_32bytes = ((line_stride + 1) >> 1) << 1;
2559 line_stride_64bytes = ((line_stride + 3) >> 2) << 2;
Googler4f18c0c2022-09-20 17:23:36 +08002560 /* need wr ddr is 32bytes aligned */
2561 if (stride_align_32bytes)
Googler9398cc32022-12-02 17:21:52 +08002562 line_stride = line_stride_32bytes;
Googler38bda472022-08-19 10:07:08 -07002563 else
Googler9398cc32022-12-02 17:21:52 +08002564 line_stride = line_stride_64bytes;
Googler4f18c0c2022-09-20 17:23:36 +08002565 return line_stride;
2566}
2567
Googler9398cc32022-12-02 17:21:52 +08002568static u32 line_stride_calc_afbc(u32 fmt_mode,
2569 u32 hsize,
2570 u32 stride_align_32bytes)
Googler4f18c0c2022-09-20 17:23:36 +08002571{
2572 u32 line_stride = 0;
2573
2574 switch (fmt_mode) {
2575 case R8:
2576 line_stride = ((hsize << 3) + 127) >> 7;
2577 break;
2578 case YUV422_8B:
2579 case RGB565:
2580 case RGBA5551:
2581 case RGBA4444:
2582 line_stride = ((hsize << 4) + 127) >> 7;
2583 break;
2584 case RGBA8888:
2585 case RGB888:
2586 case YUV422_10B:
2587 case RGBA1010102:
2588 line_stride = ((hsize << 5) + 127) >> 7;
2589 break;
2590 }
2591 /* need wr ddr is 32bytes aligned */
2592 if (stride_align_32bytes)
Googler9398cc32022-12-02 17:21:52 +08002593 line_stride = ((line_stride + 1) >> 1) << 1;
2594
Googler4f18c0c2022-09-20 17:23:36 +08002595 return line_stride;
2596}
2597
Googler4f18c0c2022-09-20 17:23:36 +08002598static void osd_update_phy_addr(u32 index)
2599{
2600 u32 line_stride, bpp;
2601 u32 fmt_mode = COLOR_INDEX_32_BGRX;
Googler9398cc32022-12-02 17:21:52 +08002602 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08002603
2604 if (osd_hw.color_info[index])
2605 fmt_mode =
2606 osd_hw.color_info[index]->color_index;
2607 bpp = osd_hw.color_info[index]->bpp / 8;
Googler9398cc32022-12-02 17:21:52 +08002608 /* 32 byte align */
2609 line_stride = line_stride_calc
2610 (fmt_mode,
Googler4f18c0c2022-09-20 17:23:36 +08002611 osd_hw.fb_gem[index].width / bpp, 1);
Googler9398cc32022-12-02 17:21:52 +08002612 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
2613 (hw_osd_reg_array[index].osd_blk1_cfg_w4,
2614 osd_hw.fb_gem[index].addr);
2615 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
2616 (hw_osd_reg_array[index].osd_blk2_cfg_w4,
Googler4f18c0c2022-09-20 17:23:36 +08002617 line_stride,
2618 0, 12);
2619}
2620
Googler9398cc32022-12-02 17:21:52 +08002621static void osd_update_mif_linear_addr(u32 index)
2622{
2623 u32 line_stride, bpp;
2624 u32 fmt_mode = COLOR_INDEX_32_BGRX;
2625 u32 output_index = get_output_device_id(index);
2626
2627 if (osd_hw.color_info[index])
2628 fmt_mode =
2629 osd_hw.color_info[index]->color_index;
2630 else
2631 return;
2632 bpp = osd_hw.color_info[index]->bpp / 8;
2633 /* 64 bytes align */
2634 line_stride = line_stride_calc
2635 (fmt_mode,
2636 osd_hw.fb_gem[index].width / bpp, 0);
2637 /* set frame addr, 8G addr, need >> 4*/
2638 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
2639 (hw_osd_reg_array[index].osd_blk1_cfg_w4,
2640 osd_hw.fb_gem[index].addr >> 4);
2641 /* set line stride */
2642 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
2643 (hw_osd_reg_array[index].osd_blk2_cfg_w4,
2644 line_stride,
2645 0, 12);
2646 /* used phyic addr */
2647 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
2648 (hw_osd_reg_array[index].osd_ctrl_stat,
2649 1, 2, 1);
2650}
2651
Googler4f18c0c2022-09-20 17:23:36 +08002652/* only need judge osd1 and osd2 index, osd3 same with osd1 */
2653static void osd_update_interlace_mode(int index)
2654{
2655 /* only called by vsync irq or rdma irq */
2656 unsigned int fb0_cfg_w0 = 0, fb1_cfg_w0 = 0;
2657 unsigned int scan_line_number = 0;
2658 unsigned int odd_even;
Googler9398cc32022-12-02 17:21:52 +08002659 u32 output_index = VIU1;
Googler4f18c0c2022-09-20 17:23:36 +08002660
2661 spin_lock_irqsave(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +08002662 if ((index & (1 << OSD1)) == (1 << OSD1)) {
2663 output_index = get_output_device_id(OSD1);
2664 fb0_cfg_w0 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
2665 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w0);
2666 }
2667 if ((index & (1 << OSD2)) == (1 << OSD2)) {
2668 output_index = get_output_device_id(OSD2);
2669 fb1_cfg_w0 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
2670 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w0);
2671 }
Googler4f18c0c2022-09-20 17:23:36 +08002672 if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) {
2673 /* 1080I */
2674 scan_line_number = ((osd_reg_read(ENCP_INFO_READ))
2675 & 0x1fff0000) >> 16;
2676 if ((osd_hw.pandata[OSD1].y_start % 2) == 0) {
2677 if (scan_line_number >= 562) {
2678 /* bottom field, odd lines*/
2679 odd_even = OSD_TYPE_BOT_FIELD;
2680 } else {
2681 /* top field, even lines*/
2682 odd_even = OSD_TYPE_TOP_FIELD;
2683 }
2684 } else {
2685 if (scan_line_number >= 562) {
2686 /* top field, even lines*/
2687 odd_even = OSD_TYPE_TOP_FIELD;
2688 } else {
2689 /* bottom field, odd lines*/
2690 odd_even = OSD_TYPE_BOT_FIELD;
2691 }
2692 }
2693 } else {
2694 if ((osd_hw.pandata[OSD1].y_start % 2) == 1) {
2695 odd_even = (osd_reg_read(ENCI_INFO_READ) & (1 << 29)) ?
2696 OSD_TYPE_TOP_FIELD : OSD_TYPE_BOT_FIELD;
2697 } else {
2698 odd_even = (osd_reg_read(ENCI_INFO_READ) & (1 << 29)) ?
2699 OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD;
2700 }
2701 }
2702 if (osd_hw.hw_rdma_en)
2703 /* when RDMA enabled, top/bottom fields changed in next vsync */
2704 odd_even = (odd_even == OSD_TYPE_TOP_FIELD) ?
2705 OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD;
2706 fb0_cfg_w0 &= ~1;
2707 fb1_cfg_w0 &= ~1;
2708 fb0_cfg_w0 |= odd_even;
2709 fb1_cfg_w0 |= odd_even;
2710 if ((index & (1 << OSD1)) == (1 << OSD1)) {
Googler9398cc32022-12-02 17:21:52 +08002711 output_index = get_output_device_id(OSD1);
2712 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_irq
2713 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w0, fb0_cfg_w0);
Googler4f18c0c2022-09-20 17:23:36 +08002714 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
Googler9398cc32022-12-02 17:21:52 +08002715 if ((osd_hw.osd_meson_dev.viu1_osd_count - 1) == OSD3) {
2716 output_index = get_output_device_id(OSD3);
2717 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_irq
2718 (hw_osd_reg_array[OSD3].osd_blk0_cfg_w0,
Googler4f18c0c2022-09-20 17:23:36 +08002719 fb0_cfg_w0);
Googler9398cc32022-12-02 17:21:52 +08002720 }
Googler4f18c0c2022-09-20 17:23:36 +08002721 }
2722 }
Googler9398cc32022-12-02 17:21:52 +08002723 if ((index & (1 << OSD2)) == (1 << OSD2)) {
2724 output_index = get_output_device_id(OSD2);
2725 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_irq
2726 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w0,
2727 fb1_cfg_w0);
2728 }
Googler4f18c0c2022-09-20 17:23:36 +08002729
2730 spin_unlock_irqrestore(&osd_lock, lock_flags);
2731}
2732
2733void osd_update_scan_mode(void)
2734{
2735 /* only called by vsync irq or rdma irq */
2736 unsigned int output_type = 0;
2737 int index = 0;
2738 int viu2_index = osd_hw.osd_meson_dev.viu2_index;
2739 int osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
2740 int has_osd3 = 0;
2741
2742 if ((osd_count - 1) == OSD3)
2743 has_osd3 = 1;
Googler9398cc32022-12-02 17:21:52 +08002744
Googler4f18c0c2022-09-20 17:23:36 +08002745 output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3;
2746 osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE;
2747 osd_hw.scan_mode[OSD2] = SCAN_MODE_PROGRESSIVE;
2748 if (has_osd3)
2749 osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE;
2750 osd_hw.scan_mode[viu2_index] = SCAN_MODE_PROGRESSIVE;
2751 switch (output_type) {
2752 case VOUT_ENCP:
2753 if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) {
2754 /* 1080i */
2755 osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE;
2756 osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
2757 if (has_osd3)
Googler9398cc32022-12-02 17:21:52 +08002758 osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE;
Googler4f18c0c2022-09-20 17:23:36 +08002759 }
2760 break;
2761 case VOUT_ENCI:
2762 if (osd_reg_read(ENCI_VIDEO_EN) & 1) {
2763 osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE;
2764 osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
2765 if (has_osd3)
Googler9398cc32022-12-02 17:21:52 +08002766 osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE;
Googler4f18c0c2022-09-20 17:23:36 +08002767 }
2768 break;
2769 }
2770 if (osd_hw.hw_cursor_en) {
2771 /* 3 layers osd don't support osd2 cursor */
2772 if (osd_hw.free_scale_enable[OSD1])
2773 osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE;
2774 if (osd_hw.osd_afbcd[OSD1].enable)
2775 osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE;
2776
2777 if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE)
2778 index |= 1 << OSD1;
2779 if (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE)
2780 index |= 1 << OSD2;
2781 } else {
2782 int i;
2783
2784 for (i = 0; i < osd_hw.osd_meson_dev.viu1_osd_count; i++) {
2785 if (osd_hw.free_scale_enable[i])
2786 osd_hw.scan_mode[i] = SCAN_MODE_PROGRESSIVE;
2787 if (osd_hw.osd_afbcd[i].enable)
2788 osd_hw.scan_mode[i] = SCAN_MODE_PROGRESSIVE;
2789 if (osd_hw.scan_mode[i] == SCAN_MODE_INTERLACE)
2790 index |= 1 << i;
2791 }
2792 }
Googler9398cc32022-12-02 17:21:52 +08002793 if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE ||
2794 osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE)
Googler4f18c0c2022-09-20 17:23:36 +08002795 osd_update_interlace_mode(index);
2796}
2797
2798static void osd_update_interlace_mode_viu2(void)
2799{
2800 /* only called by vsync irq or rdma irq */
2801 unsigned int fb3_cfg_w0 = 0;
2802 unsigned int odd_even = 0;
2803 u32 viu2_index;
2804
2805 spin_lock_irqsave(&osd_lock, lock_flags);
2806 viu2_index = osd_hw.osd_meson_dev.viu2_index;
2807 if (osd_hw.powered[viu2_index]) {
Googler9398cc32022-12-02 17:21:52 +08002808 fb3_cfg_w0 = VSYNCOSD_RD_MPEG_REG
2809 (hw_osd_reg_array[viu2_index].osd_blk0_cfg_w0);
Googler4f18c0c2022-09-20 17:23:36 +08002810 if (osd_hw.scan_mode[viu2_index] == SCAN_MODE_INTERLACE) {
2811 if ((osd_hw.pandata[viu2_index].y_start % 2) == 1) {
2812 odd_even = (osd_reg_read(ENCI_INFO_READ) &
2813 (1 << 29)) ? OSD_TYPE_TOP_FIELD :
2814 OSD_TYPE_BOT_FIELD;
2815 } else {
2816 odd_even = (osd_reg_read(ENCI_INFO_READ)
2817 & (1 << 29)) ? OSD_TYPE_BOT_FIELD :
2818 OSD_TYPE_TOP_FIELD;
2819 }
2820 }
2821 fb3_cfg_w0 &= ~1;
2822 fb3_cfg_w0 |= odd_even;
Googler9398cc32022-12-02 17:21:52 +08002823 VSYNCOSD_IRQ_WR_MPEG_REG
2824 (hw_osd_reg_array[viu2_index].osd_blk0_cfg_w0,
Googler4f18c0c2022-09-20 17:23:36 +08002825 fb3_cfg_w0);
2826 }
2827 spin_unlock_irqrestore(&osd_lock, lock_flags);
2828}
2829
2830void osd_update_scan_mode_viu2(void)
2831{
2832 /* only called by vsync irq or rdma irq */
2833 unsigned int output_type = 0;
2834 int viu2_index = osd_hw.osd_meson_dev.viu2_index;
2835
2836 output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3;
2837 osd_hw.scan_mode[viu2_index] = SCAN_MODE_PROGRESSIVE;
2838 if (osd_hw.powered[viu2_index]) {
2839 output_type = (osd_reg_read(VPU_VIU_VENC_MUX_CTRL)
2840 >> 2) & 0x3;
2841 switch (output_type) {
2842 case VOUT_ENCP:
2843 if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12))
2844 /* 1080i */
2845 osd_hw.scan_mode[viu2_index] =
2846 SCAN_MODE_INTERLACE;
2847 break;
2848 case VOUT_ENCI:
2849 if (osd_reg_read(ENCI_VIDEO_EN) & 1)
2850 osd_hw.scan_mode[viu2_index] =
2851 SCAN_MODE_INTERLACE;
2852 break;
2853 }
Googler4f18c0c2022-09-20 17:23:36 +08002854 }
2855 if (osd_hw.scan_mode[viu2_index] == SCAN_MODE_INTERLACE)
2856 osd_update_interlace_mode_viu2();
2857}
2858
2859//not rdma will call update func;
2860void walk_through_update_list(void)
2861{
2862 u32 i, j;
2863
2864 for (i = 0; i < HW_OSD_COUNT; i++) {
2865 j = 0;
2866 while (osd_hw.updated[i] && j < HW_REG_INDEX_MAX) {
2867 if (osd_hw.updated[i] & (1 << j)) {
2868 if (osd_hw.reg[j].update_func)
2869 osd_hw.reg[j].update_func(i);
2870 remove_from_update_list(i, j);
2871 }
2872 j++;
2873 }
2874 }
2875}
2876
2877/*************** for GXL/GXM hardware alpha bug workaround ***************/
2878static bool mali_afbc_get_error(void)
2879{
2880 u32 status;
2881 bool error = false;
2882
2883 status = VSYNCOSD_RD_MPEG_REG(VPU_MAFBC_IRQ_RAW_STATUS);
2884 if (status & 0x3c) {
Googler9726be62022-12-14 05:53:31 +00002885 osd_log_dbg(MODULE_BASE,
Googler9398cc32022-12-02 17:21:52 +08002886 "afbc error happened,status=0x%x\n", status);
2887 osd_hw.afbc_err_cnt[0]++;
Googler4f18c0c2022-09-20 17:23:36 +08002888 error = true;
2889 }
2890 status = VSYNCOSD_WR_MPEG_REG(VPU_MAFBC_IRQ_CLEAR, 0x3f);
2891 return error;
2892}
Googler9398cc32022-12-02 17:21:52 +08002893
2894static bool mali_afbcn_get_error(u32 index)
2895{
2896 u32 status;
2897 bool error = false;
2898 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
2899 u32 output_index = get_output_device_id(index);
2900
2901 status = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
2902 (osd_reg->vpu_mafbc_irq_raw_status);
2903 if (status & 0x3c) {
2904 osd_log_dbg(MODULE_BASE,
2905 "afbc(%d) error happened,status=0x%x\n", index, status);
2906 if (index == OSD1 || index == OSD2) {
2907 index = OSD1;
2908 osd_hw.afbc_err_cnt[index]++;
2909 index = OSD2;
2910 osd_hw.afbc_err_cnt[index]++;
2911 } else {
2912 osd_hw.afbc_err_cnt[index]++;
2913 }
2914 error = true;
2915 }
2916 status = osd_hw.osd_rdma_func[output_index].osd_rdma_wr
2917 (osd_reg->vpu_mafbc_irq_clear, 0x3f);
2918 return error;
2919}
2920
2921static u32 osd_get_hw_reset_flag(u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +08002922{
2923 u32 hw_reset_flag = HW_RESET_NONE;
2924
2925 /* check hw version */
2926 switch (osd_hw.osd_meson_dev.cpu_id) {
Googler9398cc32022-12-02 17:21:52 +08002927#ifndef CONFIG_AMLOGIC_REMOVE_OLD
Googler4f18c0c2022-09-20 17:23:36 +08002928 case __MESON_CPU_MAJOR_ID_GXTVBB:
2929 if (osd_hw.osd_afbcd[OSD1].enable)
2930 hw_reset_flag |= HW_RESET_AFBCD_REGS;
2931 break;
2932 case __MESON_CPU_MAJOR_ID_GXM:
2933 /* same bit, but gxm only reset hardware, not top reg*/
2934 if (osd_hw.osd_afbcd[OSD1].enable)
2935 hw_reset_flag |= HW_RESET_AFBCD_HARDWARE;
2936#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
2937 if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001)
2938 != 0x0) ||
2939 ((hdr_osd_reg.viu_osd1_eotf_ctl & 0x80000000)
2940 != 0) ||
2941 ((hdr_osd_reg.viu_osd1_oetf_ctl & 0xe0000000)
2942 != 0)) {
2943 hw_reset_flag |= HW_RESET_OSD1_REGS;
2944 osd_hdr_on = true;
2945 } else if (osd_hdr_on) {
2946 hw_reset_flag |= HW_RESET_OSD1_REGS;
2947 osd_hdr_on = false;
2948 }
2949#endif
2950 break;
2951 case __MESON_CPU_MAJOR_ID_GXL:
2952 case __MESON_CPU_MAJOR_ID_TXL:
2953#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
2954
2955 if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001)
2956 != 0x0) ||
2957 ((hdr_osd_reg.viu_osd1_eotf_ctl & 0x80000000)
2958 != 0) ||
2959 ((hdr_osd_reg.viu_osd1_oetf_ctl & 0xe0000000)
2960 != 0)) {
2961 hw_reset_flag |= HW_RESET_OSD1_REGS;
2962 osd_hdr_on = true;
2963 } else if (osd_hdr_on) {
2964 hw_reset_flag |= HW_RESET_OSD1_REGS;
2965 osd_hdr_on = false;
2966 }
2967#endif
2968 break;
Googler9398cc32022-12-02 17:21:52 +08002969#endif
Googler4f18c0c2022-09-20 17:23:36 +08002970 case __MESON_CPU_MAJOR_ID_G12A:
2971 case __MESON_CPU_MAJOR_ID_G12B:
2972 case __MESON_CPU_MAJOR_ID_TL1:
2973 case __MESON_CPU_MAJOR_ID_SM1:
2974 case __MESON_CPU_MAJOR_ID_TM2:
Googler9726be62022-12-14 05:53:31 +00002975 case __MESON_CPU_MAJOR_ID_SC2:
Googler9398cc32022-12-02 17:21:52 +08002976 case __MESON_CPU_MAJOR_ID_T5:
2977 case __MESON_CPU_MAJOR_ID_T5D:
2978 case __MESON_CPU_MAJOR_ID_S4:
Googler4f18c0c2022-09-20 17:23:36 +08002979 {
2980 int i, afbc_enable = 0;
2981
2982 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++)
2983 afbc_enable |= osd_hw.osd_afbcd[i].enable;
2984 if (afbc_enable &&
Googler9398cc32022-12-02 17:21:52 +08002985 osd_hw.afbc_force_reset)
Googler4f18c0c2022-09-20 17:23:36 +08002986 hw_reset_flag |= HW_RESET_MALI_AFBCD_REGS;
2987 if (afbc_enable && mali_afbc_get_error() &&
Googler9398cc32022-12-02 17:21:52 +08002988 osd_hw.afbc_status_err_reset)
Googler4f18c0c2022-09-20 17:23:36 +08002989 hw_reset_flag |= HW_RESET_MALI_AFBCD_REGS;
2990 }
2991 break;
Googler9398cc32022-12-02 17:21:52 +08002992 case __MESON_CPU_MAJOR_ID_T7:
2993 case __MESON_CPU_MAJOR_ID_T3:
2994 case __MESON_CPU_MAJOR_ID_T5W:
2995 {
2996 int i, afbc_enable = 0;
2997 u32 mali_afbc_reset;
2998
2999 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) {
3000 /* if OSDx is not in VIUx, skip it */
3001 if (!validate_osd(i, output_index))
3002 continue;
3003
3004 mali_afbc_reset = 0;
3005 afbc_enable = osd_hw.osd_afbcd[i].enable;
3006 if (afbc_enable &&
3007 osd_hw.afbc_force_reset)
3008 mali_afbc_reset = 1;
3009 if (afbc_enable && mali_afbcn_get_error(i) &&
3010 osd_hw.afbc_status_err_reset)
3011 mali_afbc_reset = 1;
3012
3013 if (mali_afbc_reset) {
3014 switch (i) {
3015 case OSD1:
3016 case OSD2:
3017 hw_reset_flag |= HW_RESET_MALI_AFBCD_REGS;
3018 break;
3019 case OSD3:
3020 hw_reset_flag |= HW_RESET_MALI_AFBCD1_REGS;
3021 break;
3022 case OSD4:
3023 hw_reset_flag |= HW_RESET_MALI_AFBCD2_REGS;
3024 break;
3025 }
3026 }
3027 }
3028 }
3029 break;
Googler4f18c0c2022-09-20 17:23:36 +08003030 default:
3031 hw_reset_flag = HW_RESET_NONE;
3032 break;
3033 }
Googler9398cc32022-12-02 17:21:52 +08003034
Googler4f18c0c2022-09-20 17:23:36 +08003035 return hw_reset_flag;
3036}
3037
Googler9398cc32022-12-02 17:21:52 +08003038void osd_hw_reset(u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +08003039{
3040 /* only called by vsync irq or rdma irq */
3041 u32 backup_mask;
3042 u32 reset_bit =
Googler9398cc32022-12-02 17:21:52 +08003043 osd_get_hw_reset_flag(output_index);
3044
3045 struct osd_rdma_fun_s *rdma_func = &osd_hw.osd_rdma_func[output_index];
3046 osd_rdma_wr_irq_op rdma_wr_irq = rdma_func->osd_rdma_wr_irq;
3047
Googler4f18c0c2022-09-20 17:23:36 +08003048
3049 backup_mask = is_backup();
3050 osd_hw.hw_reset_flag = reset_bit;
Googler4f18c0c2022-09-20 17:23:36 +08003051 spin_lock_irqsave(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +08003052 if ((reset_bit & HW_RESET_OSD1_REGS) &&
3053 !(backup_mask & HW_RESET_OSD1_REGS))
Googler4f18c0c2022-09-20 17:23:36 +08003054 reset_bit &= ~HW_RESET_OSD1_REGS;
3055
Googler9398cc32022-12-02 17:21:52 +08003056#ifndef CONFIG_AMLOGIC_REMOVE_OLD
3057 if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB &&
3058 osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) &&
3059 (reset_bit & HW_RESET_AFBCD_REGS) &&
3060 !(backup_mask & HW_RESET_AFBCD_REGS))
Googler4f18c0c2022-09-20 17:23:36 +08003061 reset_bit &= ~HW_RESET_AFBCD_REGS;
Googler9398cc32022-12-02 17:21:52 +08003062#endif
Googler4f18c0c2022-09-20 17:23:36 +08003063
Googler9398cc32022-12-02 17:21:52 +08003064 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
3065 reset_bit & HW_RESET_MALI_AFBCD_REGS &&
3066 !(backup_mask & HW_RESET_MALI_AFBCD_REGS))
Googler4f18c0c2022-09-20 17:23:36 +08003067 reset_bit &= ~HW_RESET_MALI_AFBCD_REGS;
Googler9398cc32022-12-02 17:21:52 +08003068 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
3069 reset_bit & HW_RESET_MALI_AFBCD1_REGS &&
3070 !(backup_mask & HW_RESET_MALI_AFBCD1_REGS))
3071 reset_bit &= ~HW_RESET_MALI_AFBCD1_REGS;
3072 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
3073 reset_bit & HW_RESET_MALI_AFBCD2_REGS &&
3074 !(backup_mask & HW_RESET_MALI_AFBCD2_REGS))
3075 reset_bit &= ~HW_RESET_MALI_AFBCD2_REGS;
Googler4f18c0c2022-09-20 17:23:36 +08003076
3077 if (!osd_hw.hw_rdma_en) {
3078 /* if not osd rdma, don't reset osd1 for hdr */
3079 reset_bit &= ~HW_RESET_OSD1_REGS;
3080 backup_mask &= ~HW_RESET_OSD1_REGS;
3081
Googler9398cc32022-12-02 17:21:52 +08003082 if (reset_bit) {
3083 rdma_wr_irq(VIU_SW_RESET, reset_bit);
3084 rdma_wr_irq(VIU_SW_RESET, 0);
3085 }
Googler4f18c0c2022-09-20 17:23:36 +08003086 if (reset_bit & HW_RESET_OSD1_REGS) {
3087 /* restore osd regs */
3088 int i;
3089 u32 addr;
3090 u32 base = hw_osd_reg_array[OSD1].osd_ctrl_stat;
3091
3092 for (i = 0; i < OSD_REG_BACKUP_COUNT; i++) {
3093 addr = osd_reg_backup[i];
Googler9398cc32022-12-02 17:21:52 +08003094 rdma_wr_irq(addr, osd_backup[addr - base]);
Googler4f18c0c2022-09-20 17:23:36 +08003095 }
3096 }
3097
Googler9398cc32022-12-02 17:21:52 +08003098 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC &&
3099 reset_bit & HW_RESET_AFBCD_REGS) {
Googler4f18c0c2022-09-20 17:23:36 +08003100 /* restore osd afbcd regs */
3101 int i;
3102 u32 addr;
3103 u32 value;
3104 u32 base = OSD1_AFBCD_ENABLE;
3105
3106 for (i = 0; i < OSD_AFBC_REG_BACKUP_COUNT; i++) {
3107 addr = osd_afbc_reg_backup[i];
3108 value = osd_afbc_backup[addr - base];
3109 if (addr == OSD1_AFBCD_ENABLE)
3110 value |= 0x100;
Googler9398cc32022-12-02 17:21:52 +08003111 rdma_wr_irq(addr, value);
Googler4f18c0c2022-09-20 17:23:36 +08003112 }
3113 }
Googler9398cc32022-12-02 17:21:52 +08003114 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
3115 !osd_dev_hw.multi_afbc_core &&
3116 reset_bit & HW_RESET_MALI_AFBCD_REGS) {
Googler4f18c0c2022-09-20 17:23:36 +08003117 /* restore mali afbcd regs */
3118 if (osd_hw.afbc_regs_backup) {
3119 int i;
3120 u32 addr;
3121 u32 value;
3122 u32 base = VPU_MAFBC_IRQ_MASK;
3123
3124 for (i = 0; i < MALI_AFBC_REG_BACKUP_COUNT;
3125 i++) {
3126 addr = mali_afbc_reg_backup[i];
3127 value = mali_afbc_backup[addr - base];
Googler9398cc32022-12-02 17:21:52 +08003128 rdma_wr_irq(addr, value);
Googler4f18c0c2022-09-20 17:23:36 +08003129 }
3130 }
Googler9398cc32022-12-02 17:21:52 +08003131 rdma_wr_irq(VPU_MAFBC_COMMAND, 1);
Googler4f18c0c2022-09-20 17:23:36 +08003132 }
Googler9398cc32022-12-02 17:21:52 +08003133 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
3134 osd_dev_hw.multi_afbc_core) {
3135 if (reset_bit & HW_RESET_MALI_AFBCD_REGS) {
3136 /* restore mali afbcd regs */
3137 if (osd_hw.afbc_regs_backup) {
3138 int i;
3139 u32 addr;
3140 u32 value;
3141 u32 base = VPU_MAFBC_IRQ_MASK;
3142
3143 for (i = 0; i < MALI_AFBC_REG_T7_BACKUP_COUNT;
3144 i++) {
3145 addr = mali_afbc_reg_t7_backup[i];
3146 value = mali_afbc_t7_backup[addr - base];
3147 rdma_wr_irq(addr, value);
3148 }
3149 }
3150 rdma_wr_irq(VPU_MAFBC_COMMAND, 1);
3151 }
3152 if (reset_bit & HW_RESET_MALI_AFBCD1_REGS) {
3153 /* restore mali afbcd regs */
3154 if (osd_hw.afbc_regs_backup) {
3155 int i;
3156 u32 addr;
3157 u32 value;
3158 u32 base = VPU_MAFBC1_IRQ_MASK;
3159
3160 for (i = 0; i < MALI_AFBC1_REG_T7_BACKUP_COUNT;
3161 i++) {
3162 addr = mali_afbc1_reg_t7_backup[i];
3163 value = mali_afbc1_t7_backup[addr - base];
3164 rdma_wr_irq(addr, value);
3165 }
3166 }
3167 rdma_wr_irq(VPU_MAFBC1_COMMAND, 1);
3168 }
3169 if (reset_bit & HW_RESET_MALI_AFBCD2_REGS) {
3170 /* restore mali afbcd regs */
3171 if (osd_hw.afbc_regs_backup) {
3172 int i;
3173 u32 addr;
3174 u32 value;
3175 u32 base = VPU_MAFBC2_IRQ_MASK;
3176
3177 for (i = 0; i < MALI_AFBC2_REG_T7_BACKUP_COUNT;
3178 i++) {
3179 addr = mali_afbc2_reg_t7_backup[i];
3180 value = mali_afbc2_t7_backup[addr - base];
3181 rdma_wr_irq(addr, value);
3182 }
3183 }
3184 rdma_wr_irq(VPU_MAFBC2_COMMAND, 1);
3185 }
3186 }
3187
3188 } else {
3189 osd_rdma_reset_and_flush(output_index, reset_bit);
3190 }
Googler4f18c0c2022-09-20 17:23:36 +08003191 spin_unlock_irqrestore(&osd_lock, lock_flags);
3192 /* maybe change reset bit */
3193 osd_hw.hw_reset_flag = reset_bit;
3194}
3195
3196static int notify_to_amvideo(void)
3197{
Googler9398cc32022-12-02 17:21:52 +08003198 u32 para[7];
Googler4f18c0c2022-09-20 17:23:36 +08003199
3200 para[0] = osd_vpp_misc;
3201 para[1] = osd_vpp_misc_mask;
Googler9398cc32022-12-02 17:21:52 +08003202 /* osd_vpp1_bld_ctrl */
3203 para[2] = osd_vpp1_bld_ctrl;
3204 para[3] = osd_vpp1_bld_ctrl_mask;
3205 /* osd_vpp2_bld_ctrl */
3206 para[4] = osd_vpp2_bld_ctrl;
3207 para[5] = osd_vpp2_bld_ctrl_mask;
3208 para[6] = osd_vpp_bld_ctrl_update_mask;
3209
3210 pr_debug("osd %s vpp misc:0x%08x, mask:0x%08x\n",
3211 __func__, para[0], para[1]);
3212 pr_debug("vpp1_bld_ctrl:0x%08x, mask:0x%08x,vpp2_bld_ctrl:0x%08x, mask:0x%08x, notified_mask:0x%x\n",
3213 para[2], para[3], para[4], para[5], para[6]);
3214
Googler4f18c0c2022-09-20 17:23:36 +08003215 if (osd_hw.hw_rdma_en) {
3216#ifdef CONFIG_AMLOGIC_MEDIA_VIDEO
Googler9398cc32022-12-02 17:21:52 +08003217 amvideo_notifier_call_chain(AMVIDEO_UPDATE_OSD_MODE,
3218 (void *)&para[0]);
Googler4f18c0c2022-09-20 17:23:36 +08003219#endif
3220 }
3221 return 0;
3222}
Googler38bda472022-08-19 10:07:08 -07003223
Googler9726be62022-12-14 05:53:31 +00003224int notify_preblend_to_amvideo(u32 preblend_en)
3225{
3226#ifdef CONFIG_AMLOGIC_MEDIA_VIDEO
Googler9398cc32022-12-02 17:21:52 +08003227 amvideo_notifier_call_chain
3228 (AMVIDEO_UPDATE_PREBLEND_MODE,
Googler9726be62022-12-14 05:53:31 +00003229 (void *)&preblend_en);
3230#endif
3231 return 0;
3232}
3233
Googler4f18c0c2022-09-20 17:23:36 +08003234/*************** end of GXL/GXM hardware alpha bug workaround ***************/
Googler9726be62022-12-14 05:53:31 +00003235static void viu2_osd_reg_table_init(void)
3236{
3237 int i = 0;
3238
3239 for (i = 0; i < VIU2_OSD_REG_NUM; i++) {
3240 viu2_osd_reg_table[i].val =
3241 osd_reg_read(viu2_osd_reg_table[i].addr)
3242 & viu2_osd_reg_table[i].mask;
3243 viu2_osd_table[i] = viu2_osd_reg_table[i].val;
3244 osd_log_dbg(MODULE_VIU2, "init: reg:%x = %x\n",
Googler9398cc32022-12-02 17:21:52 +08003245 viu2_osd_reg_table[i].addr,
3246 viu2_osd_reg_table[i].val);
Googler9726be62022-12-14 05:53:31 +00003247 }
3248}
3249
3250static void viu2_osd_reg_table_write(u32 index)
3251{
Googler9726be62022-12-14 05:53:31 +00003252 if ((viu2_osd_table[index] & viu2_osd_reg_table[index].mask) !=
3253 (viu2_osd_reg_table[index].val &
3254 viu2_osd_reg_table[index].mask)) {
3255 /* not same, need write to hw regs*/
3256 osd_reg_write(viu2_osd_reg_table[index].addr,
Googler9398cc32022-12-02 17:21:52 +08003257 viu2_osd_table[index] &
3258 viu2_osd_reg_table[index].mask);
Googler9726be62022-12-14 05:53:31 +00003259 viu2_osd_reg_table[index].val =
3260 viu2_osd_table[index] & viu2_osd_reg_table[index].mask;
3261 osd_log_dbg(MODULE_VIU2, "write: reg:%x = %x, update table:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003262 viu2_osd_reg_table[index].addr,
3263 viu2_osd_table[index],
3264 viu2_osd_reg_table[index].val);
Googler9726be62022-12-14 05:53:31 +00003265 }
3266}
3267
3268u32 viu2_osd_reg_read(u32 addr)
3269{
3270 int i = 0;
3271
3272 for (i = 0; i < VIU2_OSD_REG_NUM; i++) {
3273 if (addr == viu2_osd_reg_table[i].addr)
3274 return viu2_osd_table[i];
3275 }
3276 return 0;
3277}
3278
3279void viu2_osd_reg_set(u32 addr, u32 val)
3280{
3281 int i = 0;
3282
3283 osd_log_dbg2(MODULE_VIU2, "%s: reg:%x, val=%x\n",
Googler9398cc32022-12-02 17:21:52 +08003284 __func__, addr, val);
Googler9726be62022-12-14 05:53:31 +00003285 for (i = 0; i < VIU2_OSD_REG_NUM; i++) {
3286 if (addr == viu2_osd_reg_table[i].addr) {
3287 viu2_osd_table[i] = val;
3288 osd_log_dbg2(MODULE_VIU2, "%s: set table:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003289 __func__,
3290 viu2_osd_table[i]);
Googler9726be62022-12-14 05:53:31 +00003291 viu2_osd_reg_table_write(i);
3292 break;
3293 }
3294 }
3295}
3296
3297void viu2_osd_reg_set_bits(u32 addr, u32 val, u32 start, u32 len)
3298{
3299 int i = 0;
3300
3301 osd_log_dbg2(MODULE_VIU2, "%s: reg:%x,val=%x,%x,%x\n",
Googler9398cc32022-12-02 17:21:52 +08003302 __func__, addr, val, start, len);
Googler9726be62022-12-14 05:53:31 +00003303 for (i = 0; i < VIU2_OSD_REG_NUM; i++) {
3304 if (addr == viu2_osd_reg_table[i].addr) {
3305 viu2_osd_table[i] = ((viu2_osd_table[i] &
3306 ~(((1L << (len)) - 1) << (start))) |
3307 (((val) & ((1L << (len)) - 1))
3308 << (start)));
3309 osd_log_dbg2(MODULE_VIU2, "%s: set table:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003310 __func__,
3311 viu2_osd_table[i]);
Googler9726be62022-12-14 05:53:31 +00003312 viu2_osd_reg_table_write(i);
3313 break;
3314 }
3315 }
3316}
3317
3318void viu2_osd_reg_set_mask(u32 addr, u32 _mask)
3319{
3320 int i = 0;
3321
3322 osd_log_dbg2(MODULE_VIU2, "%s: reg:%x, mask:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003323 __func__, addr, _mask);
Googler9726be62022-12-14 05:53:31 +00003324 for (i = 0; i < VIU2_OSD_REG_NUM; i++) {
3325 if (addr == viu2_osd_reg_table[i].addr) {
3326 viu2_osd_table[i] = (viu2_osd_table[i] | (_mask));
3327 osd_log_dbg2(MODULE_VIU2, "%s: set table:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003328 __func__,
3329 viu2_osd_table[i]);
Googler9726be62022-12-14 05:53:31 +00003330 viu2_osd_reg_table_write(i);
3331 break;
3332 }
3333 }
3334}
3335
3336void viu2_osd_reg_clr_mask(u32 addr, u32 _mask)
3337{
3338 int i = 0;
3339
3340 osd_log_dbg2(MODULE_VIU2, "%s: reg:%x, mask:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003341 __func__, addr, _mask);
Googler9726be62022-12-14 05:53:31 +00003342 for (i = 0; i < VIU2_OSD_REG_NUM; i++) {
3343 if (addr == viu2_osd_reg_table[i].addr) {
3344 viu2_osd_table[i] = (viu2_osd_table[i] & (~(_mask)));
3345 osd_log_dbg2(MODULE_VIU2, "%s: set table:%x\n",
Googler9398cc32022-12-02 17:21:52 +08003346 __func__,
3347 viu2_osd_table[i]);
Googler9726be62022-12-14 05:53:31 +00003348 viu2_osd_reg_table_write(i);
3349 break;
3350 }
3351 }
3352}
3353
3354static void check_reg_changed(void)
3355{
3356 static u32 reg_value[72], reg_value_pre[72];
3357 int i;
3358
3359 for (i = 0; i < 7; i++)
3360 reg_value[i] = osd_reg_read(0x39b0 + i);
3361
3362 reg_value[7] = osd_reg_read(0x39bb);
3363 reg_value[8] = osd_reg_read(0x1df1);
3364 reg_value[9] = osd_reg_read(0x1df5);
3365 reg_value[10] = osd_reg_read(0x1df6);
3366 reg_value[11] = osd_reg_read(0x1d21);
3367 reg_value[12] = osd_reg_read(0x1da5);
3368
3369 for (i = 0; i < 12; i++)
3370 reg_value[13 + i] = osd_reg_read(0x1dc0 + i);
3371 for (i = 0; i < 12; i++)
3372 reg_value[25 + i] = osd_reg_read(0x3d00 + i);
3373 for (i = 0; i < 12; i++)
3374 reg_value[37 + i] = osd_reg_read(0x3d20 + i);
3375 for (i = 0; i < 6; i++)
3376 reg_value[49 + i] = osd_reg_read(0x3a13 + i);
3377 for (i = 0; i < 6; i++)
3378 reg_value[55 + i] = osd_reg_read(0x3a33 + i);
3379 for (i = 0; i < 6; i++)
3380 reg_value[61 + i] = osd_reg_read(0x3a53 + i);
3381 reg_value[68] = osd_reg_read(0x1a1b) & 0xff7f;
3382 reg_value[69] = osd_reg_read(0x1a3b) & 0xff7f;
3383 reg_value[70] = osd_reg_read(0x3d88) & 0xff7f;
3384
3385 for (i = 0; i < 72; i++) {
3386 if (reg_value[i] != reg_value_pre[i]) {
3387 if (i < 7)
3388 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3389 0x39b0 + i,
3390 reg_value_pre[i], reg_value[i]);
3391 else if (i >= 13 && i < 25)
3392 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3393 0x1dc0 + i - 13,
3394 reg_value_pre[i], reg_value[i]);
3395 else if (i >= 25 && i < 37)
3396 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3397 0x3d00 + i - 25,
3398 reg_value_pre[i], reg_value[i]);
3399 else if (i >= 37 && i < 49)
3400 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3401 0x3d20 + i - 37,
3402 reg_value_pre[i], reg_value[i]);
3403 else if (i >= 49 && i < 55)
3404 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3405 0x3a13 + i - 49,
3406 reg_value_pre[i], reg_value[i]);
3407 else if (i >= 55 && i < 61)
3408 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3409 0x3a33 + i - 55,
3410 reg_value_pre[i], reg_value[i]);
3411 else if (i >= 61 && i < 67)
3412 pr_info("Debug [0x%x] changed,pre:%x, now:%x\n",
3413 0x3a53 + i - 61,
3414 reg_value_pre[i], reg_value[i]);
3415 else if (i == 7)
3416 pr_info("Debug [0x39bb] changed,pre:%x, now:%x\n",
3417 reg_value_pre[i], reg_value[i]);
3418 else if (i == 8)
3419 pr_info("Debug [0x1df1] changed,pre:%x, now:%x\n",
3420 reg_value_pre[i], reg_value[i]);
3421 else if (i == 9)
3422 pr_info("Debug [0x1df5] changed,pre:%x, now:%x\n",
3423 reg_value_pre[i], reg_value[i]);
3424 else if (i == 10)
3425 pr_info("Debug [0x1df6] changed,pre:%x, now:%x\n",
3426 reg_value_pre[i], reg_value[i]);
3427 else if (i == 11)
3428 pr_info("Debug [0x1d21] changed,pre:%x, now:%x\n",
3429 reg_value_pre[i], reg_value[i]);
3430 else if (i == 12)
3431 pr_info("Debug [0x1da5] changed,pre:%x, now:%x\n",
3432 reg_value_pre[i], reg_value[i]);
3433 else if (i == 68)
3434 pr_info("Debug [0x1a1b] changed,pre:%x, now:%x\n",
3435 reg_value_pre[i], reg_value[i]);
3436 else if (i == 69)
3437 pr_info("Debug [0x1a3b] changed,pre:%x, now:%x\n",
3438 reg_value_pre[i], reg_value[i]);
3439 else if (i == 70)
3440 pr_info("Debug [0x3d88] changed,pre:%x, now:%x\n",
3441 reg_value_pre[i], reg_value[i]);
3442 }
3443 }
3444
3445 for (i = 0; i < 72; i++)
3446 reg_value_pre[i] = reg_value[i];
3447}
3448
Googler4f18c0c2022-09-20 17:23:36 +08003449#ifdef FIQ_VSYNC
3450static irqreturn_t vsync_isr(int irq, void *dev_id)
3451{
Googler9726be62022-12-14 05:53:31 +00003452 if (suspend_flag)
3453 return IRQ_HANDLED;
Googler4f18c0c2022-09-20 17:23:36 +08003454 wait_vsync_wakeup();
3455 return IRQ_HANDLED;
3456}
3457
3458static void osd_fiq_isr(void)
3459#else
3460static irqreturn_t vsync_isr(int irq, void *dev_id)
3461#endif
3462{
Googler9726be62022-12-14 05:53:31 +00003463 if (suspend_flag) {
3464 if (osd_log_out)
3465 pr_info("osd suspend, vsync exit\n");
3466 osd_log_out = 0;
3467 return IRQ_HANDLED;
3468 }
Googler4f18c0c2022-09-20 17:23:36 +08003469 if (!osd_hw.hw_rdma_en) {
Googler9726be62022-12-14 05:53:31 +00003470 osd_update_vsync_timestamp();
Googler4f18c0c2022-09-20 17:23:36 +08003471 osd_update_scan_mode();
3472 /* go through update list */
3473 walk_through_update_list();
3474 osd_update_3d_mode();
Googler9398cc32022-12-02 17:21:52 +08003475 osd_mali_afbc_start(VIU1);
Googler4f18c0c2022-09-20 17:23:36 +08003476 osd_update_vsync_hit();
Googler9398cc32022-12-02 17:21:52 +08003477 osd_hw_reset(VIU1);
Googler38bda472022-08-19 10:07:08 -07003478 } else {
Googler9726be62022-12-14 05:53:31 +00003479 osd_update_vsync_timestamp();
Googler9398cc32022-12-02 17:21:52 +08003480 osd_rdma_interrupt_done_clear(VPU_VPP0);
Googler38bda472022-08-19 10:07:08 -07003481 }
Googler9726be62022-12-14 05:53:31 +00003482 if (osd_hw.osd_reg_check)
3483 check_reg_changed();
Googler4f18c0c2022-09-20 17:23:36 +08003484#ifndef FIQ_VSYNC
3485 return IRQ_HANDLED;
3486#endif
3487}
3488
3489#ifdef FIQ_VSYNC
3490static irqreturn_t vsync_viu2_isr(int irq, void *dev_id)
3491{
3492 return IRQ_HANDLED;
3493}
3494
3495static void osd_viu2_fiq_isr(void)
3496#else
3497static irqreturn_t vsync_viu2_isr(int irq, void *dev_id)
3498#endif
3499{
Googler9726be62022-12-14 05:53:31 +00003500 if (suspend_flag)
3501 return IRQ_HANDLED;
3502 /* osd_update_scan_mode_viu2(); */
3503 osd_update_vsync_timestamp_viu2();
Googler9398cc32022-12-02 17:21:52 +08003504#ifndef FIQ_VSYNC
3505 return IRQ_HANDLED;
3506#endif
3507}
3508
3509#ifdef FIQ_VSYNC
3510static irqreturn_t vsync_viu3_isr(int irq, void *dev_id)
3511{
3512 return IRQ_HANDLED;
3513}
3514
3515static void vsync_viu3_isr(void)
3516#else
3517static irqreturn_t vsync_viu3_isr(int irq, void *dev_id)
3518#endif
3519{
3520 if (suspend_flag)
3521 return IRQ_HANDLED;
3522 /* osd_update_scan_mode_viu2(); */
3523 osd_update_vsync_timestamp_viu3();
3524 osd_update_vsync_hit_viu3();
Googler4f18c0c2022-09-20 17:23:36 +08003525#ifndef FIQ_VSYNC
3526 return IRQ_HANDLED;
3527#endif
3528}
3529
3530void osd_set_pxp_mode(u32 mode)
3531{
3532 pxp_mode = mode;
3533}
Googler9398cc32022-12-02 17:21:52 +08003534
Googler4f18c0c2022-09-20 17:23:36 +08003535void osd_set_afbc(u32 index, u32 enable)
3536{
Googler4f18c0c2022-09-20 17:23:36 +08003537 if (osd_hw.osd_meson_dev.afbc_type)
3538 osd_hw.osd_afbcd[index].enable = enable;
Googler38bda472022-08-19 10:07:08 -07003539 osd_log_info("afbc_type=%d,enable=%d\n",
Googler9398cc32022-12-02 17:21:52 +08003540 osd_hw.osd_meson_dev.afbc_type,
3541 osd_hw.osd_afbcd[index].enable);
Googler4f18c0c2022-09-20 17:23:36 +08003542}
3543
3544u32 osd_get_afbc(u32 index)
3545{
3546 u32 afbc_type = 0;
3547
Googler9726be62022-12-14 05:53:31 +00003548 if (osd_hw.osd_meson_dev.cpu_id ==
3549 __MESON_CPU_MAJOR_ID_GXM)
3550 afbc_type = 1;
3551 else if (osd_hw.osd_meson_dev.cpu_id >=
3552 __MESON_CPU_MAJOR_ID_G12A)
3553 afbc_type = 2;
3554 else
3555 afbc_type = 0;
Googler4f18c0c2022-09-20 17:23:36 +08003556 return afbc_type;
3557}
3558
3559u32 osd_get_reset_status(void)
3560{
3561 return osd_hw.hw_reset_flag;
3562}
3563
Googler9398cc32022-12-02 17:21:52 +08003564static void osd_wait_vsync_hw_viux(u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +08003565{
3566 unsigned long timeout;
Googler9398cc32022-12-02 17:21:52 +08003567 wait_queue_head_t *wait_queue = &osd_rdma_vpp0_done_wq;
Googler4f18c0c2022-09-20 17:23:36 +08003568
3569 if (osd_hw.fb_drvier_probe) {
Googler9398cc32022-12-02 17:21:52 +08003570 /* for the independent viu2 HW module,
3571 * use the latch, waiting for vsync (not rdma interrupt).
3572 */
3573 if (osd_hw.osd_meson_dev.has_viu2 && output_index == VIU2) {
3574 osd_wait_vsync_event_viu2();
3575 return;
3576 }
Googler4f18c0c2022-09-20 17:23:36 +08003577
Googler9398cc32022-12-02 17:21:52 +08003578 vsync_hit[output_index] = false;
3579
3580 if (pxp_mode) {
Googler4f18c0c2022-09-20 17:23:36 +08003581 timeout = msecs_to_jiffies(50);
Googler9398cc32022-12-02 17:21:52 +08003582 } else {
3583 struct vinfo_s *vinfo = NULL;
Googler4f18c0c2022-09-20 17:23:36 +08003584
Googler9398cc32022-12-02 17:21:52 +08003585 switch (output_index) {
3586 case VIU1:
3587 #ifdef CONFIG_AMLOGIC_VOUT_SERVE
3588 vinfo = get_current_vinfo();
3589 #endif
3590 wait_queue = &osd_rdma_vpp0_done_wq;
3591 break;
3592 case VIU2:
3593 #ifdef CONFIG_AMLOGIC_VOUT2_SERVE
3594 vinfo = get_current_vinfo2();
3595 #endif
3596 wait_queue = &osd_rdma_vpp1_done_wq;
3597 break;
3598 case VIU3:
3599 #ifdef CONFIG_AMLOGIC_VOUT3_SERVE
3600 vinfo = get_current_vinfo3();
3601 #endif
3602 wait_queue = &osd_rdma_vpp2_done_wq;
3603 break;
3604 default:
3605 osd_log_err("%s, set output_index %u error\n",
3606 __func__, output_index);
3607 break;
3608
3609 };
3610 if (vinfo && vinfo->name &&
3611 (!strcmp(vinfo->name, "invalid") ||
3612 !strcmp(vinfo->name, "null")))
Googler4f18c0c2022-09-20 17:23:36 +08003613 timeout = msecs_to_jiffies(1);
Googler9398cc32022-12-02 17:21:52 +08003614 else
Googler4f18c0c2022-09-20 17:23:36 +08003615 timeout = msecs_to_jiffies(1000);
3616 }
Googler9398cc32022-12-02 17:21:52 +08003617 wait_event_interruptible_timeout(*wait_queue,
3618 vsync_hit[output_index], timeout);
Googler9726be62022-12-14 05:53:31 +00003619 }
3620}
3621
3622void osd_wait_vsync_hw(u32 index)
3623{
3624 u32 output_index = get_output_device_id(index);
3625
Googler9398cc32022-12-02 17:21:52 +08003626 osd_wait_vsync_hw_viux(output_index);
Googler9726be62022-12-14 05:53:31 +00003627}
3628
Googler4f18c0c2022-09-20 17:23:36 +08003629s64 osd_wait_vsync_event(void)
3630{
3631 unsigned long timeout;
Googler9398cc32022-12-02 17:21:52 +08003632 ktime_t stime;
Googler4f18c0c2022-09-20 17:23:36 +08003633
Googler9398cc32022-12-02 17:21:52 +08003634 stime = ktime_get();
Googler4f18c0c2022-09-20 17:23:36 +08003635 if (pxp_mode)
3636 timeout = msecs_to_jiffies(50);
3637 else
3638 timeout = msecs_to_jiffies(1000);
3639
3640 /* waiting for 10ms. */
Googler9726be62022-12-14 05:53:31 +00003641 wait_event_interruptible_timeout(osd_vsync_wq,
Googler9398cc32022-12-02 17:21:52 +08003642 (timestamp[VIU1] > stime) ? true : false, timeout);
Googler9726be62022-12-14 05:53:31 +00003643 return timestamp[VIU1];
3644}
3645
3646s64 osd_wait_vsync_event_viu2(void)
3647{
3648 unsigned long timeout;
Googler9398cc32022-12-02 17:21:52 +08003649 ktime_t stime;
Googler9726be62022-12-14 05:53:31 +00003650
Googler9398cc32022-12-02 17:21:52 +08003651 stime = ktime_get();
Googler9726be62022-12-14 05:53:31 +00003652
3653 if (pxp_mode)
3654 timeout = msecs_to_jiffies(50);
3655 else
3656 timeout = msecs_to_jiffies(1000);
3657
3658 /* waiting for 10ms. */
3659 wait_event_interruptible_timeout(osd_vsync2_wq,
Googler9398cc32022-12-02 17:21:52 +08003660 (timestamp[VIU2] > stime) ? true : false, timeout);
Googler9726be62022-12-14 05:53:31 +00003661
3662 return timestamp[VIU2];
Googler4f18c0c2022-09-20 17:23:36 +08003663}
3664
Googler9398cc32022-12-02 17:21:52 +08003665s64 osd_wait_vsync_event_viu3(void)
3666{
3667 unsigned long timeout;
3668 ktime_t stime;
3669
3670 stime = ktime_get();
3671
3672 if (pxp_mode)
3673 timeout = msecs_to_jiffies(50);
3674 else
3675 timeout = msecs_to_jiffies(1000);
3676
3677 /* waiting for 10ms. */
3678 wait_event_interruptible_timeout(osd_vsync3_wq,
3679 (timestamp[VIU3] > stime) ? true : false, timeout);
3680
3681 return timestamp[VIU3];
3682}
3683
Googler4f18c0c2022-09-20 17:23:36 +08003684int is_interlaced(struct vinfo_s *vinfo)
3685{
3686 if (!vinfo)
3687 return 0;
3688 if (vinfo->mode == VMODE_CVBS)
3689 return 1;
3690 if (vinfo->height != vinfo->field_height)
3691 return 1;
3692 else
3693 return 0;
3694}
3695
3696int osd_set_scan_mode(u32 index)
3697{
3698 struct vinfo_s *vinfo = NULL;
3699 u32 data32 = 0x0;
3700 s32 y_end = 0;
3701 u32 output_index;
Googler9398cc32022-12-02 17:21:52 +08003702 u32 scale_input_w;
Googler4f18c0c2022-09-20 17:23:36 +08003703
3704 output_index = get_output_device_id(index);
3705 osd_hw.scan_mode[index] = SCAN_MODE_PROGRESSIVE;
3706 if (output_index == VIU1)
Googler9398cc32022-12-02 17:21:52 +08003707#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +08003708 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08003709#endif
Googler4f18c0c2022-09-20 17:23:36 +08003710#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
3711 else if (output_index == VIU2)
3712 vinfo = get_current_vinfo2();
3713#endif
Googler9398cc32022-12-02 17:21:52 +08003714 if (vinfo && vinfo->name && (strcmp(vinfo->name, "invalid") &&
3715 strcmp(vinfo->name, "null"))) {
Googler4f18c0c2022-09-20 17:23:36 +08003716 osd_hw.scale_workaround = 0;
3717 if (osd_auto_adjust_filter) {
3718 osd_h_filter_mode = 1;
3719 osd_v_filter_mode = 1;
3720 }
Googler9726be62022-12-14 05:53:31 +00003721
3722 scale_input_w = osd_hw.free_src_data[index].x_end -
3723 osd_hw.free_src_data[index].x_start + 1;
Googler9398cc32022-12-02 17:21:52 +08003724 if ((osd_hw.fb_for_4k2k ||
Googler9726be62022-12-14 05:53:31 +00003725 scale_input_w > FREE_SCALE_MAX_WIDTH) &&
Googler9398cc32022-12-02 17:21:52 +08003726 osd_hw.free_scale_enable[index])
3727 osd_hw.scale_workaround = 1;
3728
Googler4f18c0c2022-09-20 17:23:36 +08003729 if (is_interlaced(vinfo)) {
3730 osd_hw.scan_mode[index] = SCAN_MODE_INTERLACE;
3731 if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL)
3732 osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
3733 y_end = osd_hw.free_src_data[index].y_end;
Googler9398cc32022-12-02 17:21:52 +08003734 if (vinfo->width == 720 &&
3735 vinfo->height == 480) {
Googler4f18c0c2022-09-20 17:23:36 +08003736 if (osd_hw.free_scale_mode[index]) {
3737 osd_hw.field_out_en[output_index] = 1;
3738 switch (y_end) {
3739 case 719:
3740 osd_hw.bot_type = 2;
3741 break;
3742 case 1079:
3743 osd_hw.bot_type = 3;
3744 break;
3745 default:
3746 osd_hw.bot_type = 2;
3747 break;
3748 }
3749 }
3750 if (osd_auto_adjust_filter) {
3751 osd_h_filter_mode = 6;
3752 osd_v_filter_mode = 6;
3753 }
Googler9398cc32022-12-02 17:21:52 +08003754 } else if (vinfo->width == 720 &&
3755 vinfo->height == 576) {
Googler4f18c0c2022-09-20 17:23:36 +08003756 if (osd_hw.free_scale_mode[index]) {
3757 osd_hw.field_out_en[output_index] = 1;
3758 switch (y_end) {
3759 case 719:
3760 osd_hw.bot_type = 2;
3761 break;
3762 case 1079:
3763 osd_hw.bot_type = 2;
3764 break;
3765 default:
3766 osd_hw.bot_type = 2;
3767 break;
3768 }
3769 }
3770 if (osd_auto_adjust_filter) {
3771 osd_h_filter_mode = 6;
3772 osd_v_filter_mode = 6;
3773 }
3774
Googler9398cc32022-12-02 17:21:52 +08003775 } else if (vinfo->width == 1920 &&
3776 vinfo->height == 1080) {
Googler4f18c0c2022-09-20 17:23:36 +08003777 if (osd_hw.free_scale_mode[index]) {
3778 osd_hw.field_out_en[output_index] = 1;
3779 switch (y_end) {
3780 case 719:
3781 osd_hw.bot_type = 1;
3782 break;
3783 case 1079:
3784 osd_hw.bot_type = 2;
3785 break;
3786 default:
3787 osd_hw.bot_type = 1;
3788 break;
3789 }
3790 }
3791 }
3792 } else {
Googler9398cc32022-12-02 17:21:52 +08003793 if ((vinfo->width == 3840 &&
3794 vinfo->height == 2160) ||
3795 (vinfo->width == 4096 &&
3796 vinfo->height == 2160)) {
Googler4f18c0c2022-09-20 17:23:36 +08003797 osd_hw.field_out_en[output_index] = 0;
Googler9398cc32022-12-02 17:21:52 +08003798 } else if ((vinfo->width == 720 &&
3799 vinfo->height == 480) ||
3800 (vinfo->width == 720 &&
3801 vinfo->height == 576)) {
Googler4f18c0c2022-09-20 17:23:36 +08003802 if (osd_auto_adjust_filter) {
3803 osd_h_filter_mode = 6;
3804 osd_v_filter_mode = 6;
3805 }
3806 if (osd_hw.free_scale_mode[index])
3807 osd_hw.field_out_en[output_index] = 0;
3808 } else {
3809 if (osd_hw.free_scale_mode[index])
3810 osd_hw.field_out_en[output_index] = 0;
3811 }
3812 }
3813 }
3814 if (osd_hw.free_scale_enable[index])
3815 osd_hw.scan_mode[index] = SCAN_MODE_PROGRESSIVE;
3816 if (osd_hw.osd_afbcd[index].enable)
3817 osd_hw.scan_mode[index] = SCAN_MODE_PROGRESSIVE;
3818 if (index == OSD2) {
3819 if (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE)
3820 return 1;
Googler9398cc32022-12-02 17:21:52 +08003821 data32 = (osd_hw.osd_rdma_func[output_index].osd_rdma_rd
3822 (hw_osd_reg_array[index].osd_blk0_cfg_w0) & 3) >> 1;
3823 } else {
3824 data32 = (osd_hw.osd_rdma_func[output_index].osd_rdma_rd
3825 (hw_osd_reg_array[index].osd_blk0_cfg_w0) & 3) >> 1;
3826 }
Googler4f18c0c2022-09-20 17:23:36 +08003827 if (data32 == osd_hw.scan_mode[index])
3828 return 1;
3829 else
3830 return 0;
3831}
3832
3833void osd_set_gbl_alpha_hw(u32 index, u32 gbl_alpha)
3834{
3835 /* normalized */
3836 if (gbl_alpha == 0xff)
3837 gbl_alpha = 0x100;
3838 if (osd_hw.gbl_alpha[index] != gbl_alpha) {
3839 osd_hw.gbl_alpha[index] = gbl_alpha;
3840 add_to_update_list(index, OSD_GBL_ALPHA);
Googler9726be62022-12-14 05:53:31 +00003841 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08003842 }
3843}
3844
3845u32 osd_get_gbl_alpha_hw(u32 index)
3846{
3847 return osd_hw.gbl_alpha[index];
3848}
3849
3850void osd_set_line_n_rdma(u32 line_n_rdma)
3851{
3852 if (osd_hw.line_n_rdma != line_n_rdma) {
3853 osd_hw.line_n_rdma = line_n_rdma;
3854 if (osd_hw.line_n_rdma)
3855 enable_line_n_rdma();
3856 else
Googler9398cc32022-12-02 17:21:52 +08003857 enable_vsync_rdma(VPU_VPP0);
Googler4f18c0c2022-09-20 17:23:36 +08003858 }
3859}
3860
3861u32 osd_get_line_n_rdma(void)
3862{
3863 return osd_hw.line_n_rdma;
3864}
3865
Googler9726be62022-12-14 05:53:31 +00003866void osd_set_blend_bypass(int index, u32 blend_bypass)
3867{
Googler9398cc32022-12-02 17:21:52 +08003868 if (blend_bypass != osd_hw.blend_bypass[index]) {
3869 osd_hw.blend_bypass[index] = blend_bypass;
Googler9726be62022-12-14 05:53:31 +00003870 if (blend_bypass) {
3871 VSYNCOSD_WR_MPEG_REG_BITS
3872 (hw_osd_reg_array[index].osd_mali_unpack_ctrl,
3873 0x0, 28, 1);
Googler9398cc32022-12-02 17:21:52 +08003874 if (osd_dev_hw.new_blend_bypass) {
3875 VSYNCOSD_WR_MPEG_REG_BITS
3876 (hw_osd_reg_array[index].vpp_osd1_scale_ctrl,
3877 0x1, 2, 1);
3878 } else {
3879 VSYNCOSD_WR_MPEG_REG_BITS
3880 (VIU_OSD_BLEND_CTRL,
3881 0x1, 26, 1);
3882 }
3883 } else {
3884 if (osd_dev_hw.new_blend_bypass) {
3885 VSYNCOSD_WR_MPEG_REG_BITS
3886 (hw_osd_reg_array[index].vpp_osd1_scale_ctrl,
3887 0x0, 2, 1);
3888 } else {
3889 VSYNCOSD_WR_MPEG_REG_BITS
3890 (VIU_OSD_BLEND_CTRL,
3891 0x0, 26, 1);
3892 }
Googler9726be62022-12-14 05:53:31 +00003893 }
3894 }
3895}
3896
Googler9398cc32022-12-02 17:21:52 +08003897u32 osd_get_blend_bypass(u32 index)
Googler9726be62022-12-14 05:53:31 +00003898{
Googler9398cc32022-12-02 17:21:52 +08003899 return osd_hw.blend_bypass[index];
Googler9726be62022-12-14 05:53:31 +00003900}
3901
Googler4f18c0c2022-09-20 17:23:36 +08003902void osd_set_color_key_hw(u32 index, u32 color_index, u32 colorkey)
3903{
3904 u8 r = 0, g = 0, b = 0, a = (colorkey & 0xff000000) >> 24;
3905 u32 data32;
3906
3907 colorkey &= 0x00ffffff;
3908 switch (color_index) {
3909 case COLOR_INDEX_16_655:
3910 r = (colorkey >> 10 & 0x3f) << 2;
3911 g = (colorkey >> 5 & 0x1f) << 3;
3912 b = (colorkey & 0x1f) << 3;
3913 break;
3914 case COLOR_INDEX_16_844:
3915 r = colorkey >> 8 & 0xff;
3916 g = (colorkey >> 4 & 0xf) << 4;
3917 b = (colorkey & 0xf) << 4;
3918 break;
3919 case COLOR_INDEX_16_565:
3920 r = (colorkey >> 11 & 0x1f) << 3;
3921 g = (colorkey >> 5 & 0x3f) << 2;
3922 b = (colorkey & 0x1f) << 3;
3923 break;
3924 case COLOR_INDEX_24_888_B:
3925 b = colorkey >> 16 & 0xff;
3926 g = colorkey >> 8 & 0xff;
3927 r = colorkey & 0xff;
3928 break;
3929 case COLOR_INDEX_24_RGB:
3930 case COLOR_INDEX_YUV_422:
3931 r = colorkey >> 16 & 0xff;
3932 g = colorkey >> 8 & 0xff;
3933 b = colorkey & 0xff;
3934 break;
3935 }
3936 data32 = r << 24 | g << 16 | b << 8 | a;
3937 if (osd_hw.color_key[index] != data32) {
3938 osd_hw.color_key[index] = data32;
3939 osd_log_dbg2(MODULE_BASE,
Googler9398cc32022-12-02 17:21:52 +08003940 "bpp:%d--r:0x%x g:0x%x b:0x%x ,a:0x%x\n",
3941 color_index, r, g, b, a);
Googler4f18c0c2022-09-20 17:23:36 +08003942 add_to_update_list(index, OSD_COLOR_KEY);
Googler9726be62022-12-14 05:53:31 +00003943 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08003944 }
3945}
Googler9398cc32022-12-02 17:21:52 +08003946
Googler4f18c0c2022-09-20 17:23:36 +08003947void osd_srckey_enable_hw(u32 index, u8 enable)
3948{
3949 if (enable != osd_hw.color_key_enable[index]) {
3950 osd_hw.color_key_enable[index] = enable;
3951 add_to_update_list(index, OSD_COLOR_KEY_ENABLE);
Googler9726be62022-12-14 05:53:31 +00003952 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08003953 }
3954}
3955
3956void osd_set_color_mode(u32 index, const struct color_bit_define_s *color)
3957{
3958 if (color != osd_hw.color_info[index]) {
3959 osd_hw.color_info[index] = color;
3960 osd_hw.color_backup[index] = color;
3961 add_to_update_list(index, OSD_COLOR_MODE);
3962 }
3963}
3964
Googler9398cc32022-12-02 17:21:52 +08003965void osd_update_disp_axis_hw(u32 index,
3966 u32 display_h_start,
3967 u32 display_h_end,
3968 u32 display_v_start,
3969 u32 display_v_end,
3970 u32 xoffset,
3971 u32 yoffset,
3972 u32 mode_change)
Googler4f18c0c2022-09-20 17:23:36 +08003973{
3974 struct pandata_s disp_data;
3975 struct pandata_s pan_data;
3976
Googler9398cc32022-12-02 17:21:52 +08003977 if (!osd_hw.color_info[index])
Googler4f18c0c2022-09-20 17:23:36 +08003978 return;
3979 disp_data.x_start = display_h_start;
3980 disp_data.y_start = display_v_start;
3981 disp_data.x_end = display_h_end;
3982 disp_data.y_end = display_v_end;
3983 pan_data.x_start = xoffset;
3984 pan_data.x_end = xoffset +
3985 osd_hw.pandata[index].x_end -
3986 osd_hw.pandata[index].x_start;
3987#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
3988 pan_data.y_start = osd_hw.pandata[index].y_start;
3989 pan_data.y_end = osd_hw.pandata[index].y_start +
3990 osd_hw.pandata[index].y_end - osd_hw.pandata[index].y_start;
3991#else
3992 pan_data.y_start = yoffset;
3993 pan_data.y_end = yoffset +
3994 osd_hw.pandata[index].y_end - osd_hw.pandata[index].y_start;
3995#endif
3996 /* if output mode change then reset pan ofFfset. */
3997 memcpy(&osd_hw.pandata[index], &pan_data, sizeof(struct pandata_s));
3998 memcpy(&osd_hw.dispdata[index], &disp_data, sizeof(struct pandata_s));
3999 memcpy(&osd_hw.dispdata_backup[index],
Googler9398cc32022-12-02 17:21:52 +08004000 &disp_data, sizeof(struct pandata_s));
4001 osd_log_info("%s:pan_data(%d,%d,%d,%d)\n",
4002 __func__,
4003 pan_data.x_start,
4004 pan_data.y_start,
4005 pan_data.x_end,
4006 pan_data.y_end);
4007 osd_log_info("%s:dispdata(%d,%d,%d,%d)\n",
4008 __func__,
4009 disp_data.x_start,
4010 disp_data.y_start,
4011 disp_data.x_end,
4012 disp_data.y_end);
Googler4f18c0c2022-09-20 17:23:36 +08004013 spin_lock_irqsave(&osd_lock, lock_flags);
4014 if (mode_change) /* modify pandata . */
4015 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
4016 osd_hw.reg[DISP_GEOMETRY].update_func(index);
4017 osd_update_window_axis = true;
4018 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +00004019 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004020}
4021
4022void osd_setup_hw(u32 index,
4023 struct osd_ctl_s *osd_ctl,
4024 u32 xoffset,
4025 u32 yoffset,
4026 u32 xres,
4027 u32 yres,
4028 u32 xres_virtual,
4029 u32 yres_virtual,
4030 u32 disp_start_x,
4031 u32 disp_start_y,
4032 u32 disp_end_x,
4033 u32 disp_end_y,
Googler9398cc32022-12-02 17:21:52 +08004034 phys_addr_t fbmem,
Googler4f18c0c2022-09-20 17:23:36 +08004035 phys_addr_t *afbc_fbmem,
4036 const struct color_bit_define_s *color)
4037{
4038 struct pandata_s disp_data;
4039 struct pandata_s pan_data;
4040 int update_color_mode = 0;
4041 int update_geometry = 0;
4042 u32 w = (color->bpp * xres_virtual + 7) >> 3;
4043 u32 i;
4044
4045 osd_hw.buffer_alloc[index] = 1;
4046 pan_data.x_start = xoffset;
4047 pan_data.y_start = yoffset;
4048 disp_data.x_start = disp_start_x;
4049 disp_data.y_start = disp_start_y;
4050
4051 pan_data.x_end = xoffset + xres - 1;
4052 pan_data.y_end = yoffset + yres - 1;
4053 disp_data.x_end = disp_end_x;
4054 disp_data.y_end = disp_end_y;
4055
4056 /* need always set color mode for osd2 */
Googler9398cc32022-12-02 17:21:52 +08004057 if (color != osd_hw.color_info[index] ||
4058 (index == (osd_hw.osd_meson_dev.osd_count - 1))) {
Googler4f18c0c2022-09-20 17:23:36 +08004059 update_color_mode = 1;
4060 osd_hw.color_info[index] = color;
4061 osd_hw.color_backup[index] = color;
4062 }
4063
Googler9398cc32022-12-02 17:21:52 +08004064 if (osd_hw.fb_gem[index].addr != fbmem ||
4065 osd_hw.fb_gem[index].width != w ||
4066 osd_hw.fb_gem[index].height != yres_virtual) {
Googler4f18c0c2022-09-20 17:23:36 +08004067 osd_hw.fb_gem[index].addr = fbmem;
4068 osd_hw.fb_gem[index].width = w;
4069 osd_hw.fb_gem[index].height = yres_virtual;
4070 if (osd_hw.osd_afbcd[index].enable == ENABLE &&
Googler9398cc32022-12-02 17:21:52 +08004071 afbc_fbmem) {
Googler4f18c0c2022-09-20 17:23:36 +08004072 osd_hw.osd_afbcd[index].frame_width = xres;
4073 /* osd_hw.osd_afbcd[index].frame_height =
4074 * ALIGN_CALC(yres, 16) +
4075 * ALIGN_CALC(yres, 64) / 64;
4076 */
4077 osd_hw.osd_afbcd[index].frame_height = yres;
4078 for (i = 0; i < OSD_MAX_BUF_NUM; i++)
4079 osd_hw.osd_afbcd[index].addr[i] =
Googler9398cc32022-12-02 17:21:52 +08004080 afbc_fbmem[i];
Googler4f18c0c2022-09-20 17:23:36 +08004081 osd_hw.osd_afbcd[index].phy_addr =
4082 osd_hw.osd_afbcd[index].addr[0];
Googler9398cc32022-12-02 17:21:52 +08004083
Googler4f18c0c2022-09-20 17:23:36 +08004084 /* we need update geometry
4085 * and color mode for afbc mode
4086 * update_geometry = 1;
4087 * update_color_mode = 1;
4088 */
4089 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
4090 if (xres <= 128)
4091 osd_hw.osd_afbcd[index]
4092 .conv_lbuf_len = 32;
4093 else if (xres <= 256)
4094 osd_hw.osd_afbcd[index]
4095 .conv_lbuf_len = 64;
4096 else if (xres <= 512)
4097 osd_hw.osd_afbcd[index]
4098 .conv_lbuf_len = 128;
4099 else if (xres <= 1024)
4100 osd_hw.osd_afbcd[index]
4101 .conv_lbuf_len = 256;
4102 else if (xres <= 2048)
4103 osd_hw.osd_afbcd[index]
4104 .conv_lbuf_len = 512;
4105 else
4106 osd_hw.osd_afbcd[index]
4107 .conv_lbuf_len = 1024;
4108 } else if (osd_hw.osd_meson_dev.afbc_type
4109 == MALI_AFBC)
4110 osd_hw.osd_afbcd[index].out_addr_id = index + 1;
4111 }
4112 osd_hw.fb_gem[index].xres = xres;
4113 osd_hw.fb_gem[index].yres = yres;
4114 osd_log_info("osd[%d] canvas.idx =0x%x\n",
Googler9398cc32022-12-02 17:21:52 +08004115 index, osd_hw.fb_gem[index].canvas_idx);
4116 osd_log_info("osd[%d] canvas.addr=0x%lx\n",
4117 index, osd_hw.fb_gem[index].addr);
Googler4f18c0c2022-09-20 17:23:36 +08004118 osd_log_info("osd[%d] canvas.width=%d\n",
Googler9398cc32022-12-02 17:21:52 +08004119 index, osd_hw.fb_gem[index].width);
Googler4f18c0c2022-09-20 17:23:36 +08004120 osd_log_info("osd[%d] canvas.height=%d\n",
Googler9398cc32022-12-02 17:21:52 +08004121 index, osd_hw.fb_gem[index].height);
Googler4f18c0c2022-09-20 17:23:36 +08004122 osd_log_info("osd[%d] frame.width=%d\n",
Googler9398cc32022-12-02 17:21:52 +08004123 index, osd_hw.fb_gem[index].xres);
Googler4f18c0c2022-09-20 17:23:36 +08004124 osd_log_info("osd[%d] frame.height=%d\n",
Googler9398cc32022-12-02 17:21:52 +08004125 index, osd_hw.fb_gem[index].yres);
Googler4f18c0c2022-09-20 17:23:36 +08004126 osd_log_info("osd[%d] out_addr_id =0x%x\n",
Googler9398cc32022-12-02 17:21:52 +08004127 index, osd_hw.osd_afbcd[index].out_addr_id);
Googler4f18c0c2022-09-20 17:23:36 +08004128
4129 if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE)
4130 osd_update_phy_addr(0);
Googler9398cc32022-12-02 17:21:52 +08004131 else if (osd_hw.osd_meson_dev.mif_linear)
4132 osd_update_mif_linear_addr(index);
Googler4f18c0c2022-09-20 17:23:36 +08004133#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler9398cc32022-12-02 17:21:52 +08004134 else
Googler4f18c0c2022-09-20 17:23:36 +08004135 canvas_config(osd_hw.fb_gem[index].canvas_idx,
Googler9398cc32022-12-02 17:21:52 +08004136 osd_hw.fb_gem[index].addr,
4137 CANVAS_ALIGNED
4138 (osd_hw.fb_gem[index].width),
4139 osd_hw.fb_gem[index].height,
4140 CANVAS_ADDR_NOWRAP,
4141 CANVAS_BLKMODE_LINEAR);
Googler4f18c0c2022-09-20 17:23:36 +08004142#endif
4143 }
4144
4145 /* osd blank only control by /sys/class/graphcis/fbx/blank */
Googler4f18c0c2022-09-20 17:23:36 +08004146 if (memcmp(&pan_data, &osd_hw.pandata[index],
Googler9398cc32022-12-02 17:21:52 +08004147 sizeof(struct pandata_s)) != 0 ||
Googler4f18c0c2022-09-20 17:23:36 +08004148 memcmp(&disp_data, &osd_hw.dispdata[index],
Googler9398cc32022-12-02 17:21:52 +08004149 sizeof(struct pandata_s)) != 0) {
Googler4f18c0c2022-09-20 17:23:36 +08004150 update_geometry = 1;
4151 memcpy(&osd_hw.pandata[index], &pan_data,
Googler9398cc32022-12-02 17:21:52 +08004152 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08004153 memcpy(&osd_hw.dispdata[index], &disp_data,
Googler9398cc32022-12-02 17:21:52 +08004154 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08004155 memcpy(&osd_hw.dispdata_backup[index], &disp_data,
Googler9398cc32022-12-02 17:21:52 +08004156 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08004157 osd_hw.src_data[index].x = osd_hw.pandata[index].x_start;
4158 osd_hw.src_data[index].y = osd_hw.pandata[index].y_start;
4159 osd_hw.src_data[index].w = osd_hw.pandata[index].x_end
4160 - osd_hw.pandata[index].x_start + 1;
4161 osd_hw.src_data[index].h = osd_hw.pandata[index].y_end
4162 - osd_hw.pandata[index].y_start + 1;
Googler9726be62022-12-14 05:53:31 +00004163 osd_update_disp_src_size(index);
Googler4f18c0c2022-09-20 17:23:36 +08004164 }
4165 spin_lock_irqsave(&osd_lock, lock_flags);
4166 if (update_color_mode)
4167 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
4168 if (update_geometry)
4169 osd_hw.reg[DISP_GEOMETRY].update_func(index);
4170 spin_unlock_irqrestore(&osd_lock, lock_flags);
4171
4172 if (osd_hw.antiflicker_mode)
4173 osd_antiflicker_update_pan(yoffset, yres);
4174 if (osd_hw.clone[index])
4175 osd_clone_pan(index, yoffset, 0);
4176#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
4177 osd_ext_clone_pan(index);
4178#endif
Googler9726be62022-12-14 05:53:31 +00004179 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004180}
4181
4182void osd_setpal_hw(u32 index,
4183 unsigned int regno,
4184 unsigned int red,
4185 unsigned int green,
4186 unsigned int blue,
4187 unsigned int transp
4188 )
4189{
Googler9398cc32022-12-02 17:21:52 +08004190 u32 output_index = get_output_device_id(index);
4191
4192 if (osd_hw.osd_meson_dev.has_lut) {
Googler4f18c0c2022-09-20 17:23:36 +08004193 if (regno < 256) {
4194 u32 pal;
4195
4196 pal = ((red & 0xff) << 24) |
4197 ((green & 0xff) << 16) |
4198 ((blue & 0xff) << 8) |
4199 (transp & 0xff);
4200 spin_lock_irqsave(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +08004201 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
4202 (hw_osd_reg_array[index].osd_color_addr,
Googler4f18c0c2022-09-20 17:23:36 +08004203 regno);
Googler9398cc32022-12-02 17:21:52 +08004204 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
4205 (hw_osd_reg_array[index].osd_color, pal);
Googler4f18c0c2022-09-20 17:23:36 +08004206 spin_unlock_irqrestore(&osd_lock, lock_flags);
4207 }
4208 }
4209}
4210
4211void osd_get_order_hw(u32 index, u32 *order)
4212{
4213 *order = osd_hw.order[index] & 0x3;
4214}
4215
4216void osd_set_order_hw(u32 index, u32 order)
4217{
Googler4f18c0c2022-09-20 17:23:36 +08004218 osd_hw.order[index] = order;
4219 //add_to_update_list(index, OSD_CHANGE_ORDER);
4220 //osd_wait_vsync_hw();
4221}
4222
4223/* osd free scale mode */
4224static void osd_set_free_scale_enable_mode1(u32 index, u32 enable)
4225{
4226 unsigned int h_enable = 0;
4227 unsigned int v_enable = 0;
4228 int ret = 0;
4229
4230 if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE)
4231 return;
4232 h_enable = (enable & 0xffff0000 ? 1 : 0);
4233 v_enable = (enable & 0xffff ? 1 : 0);
4234 osd_hw.free_scale[index].h_enable = h_enable;
4235 osd_hw.free_scale[index].v_enable = v_enable;
4236 osd_hw.free_scale_backup[index].h_enable = h_enable;
4237 osd_hw.free_scale_backup[index].v_enable = v_enable;
4238 osd_hw.free_scale_enable[index] = enable;
4239 osd_hw.free_scale_enable_backup[index] = enable;
4240 if (osd_hw.free_scale_enable[index]) {
4241 ret = osd_set_scan_mode(index);
4242 spin_lock_irqsave(&osd_lock, lock_flags);
4243 if (ret)
4244 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
4245 osd_hw.reg[OSD_FREESCALE_COEF].update_func(index);
4246 osd_hw.reg[DISP_GEOMETRY].update_func(index);
4247 osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(index);
4248 osd_hw.reg[OSD_ENABLE].update_func(index);
4249 spin_unlock_irqrestore(&osd_lock, lock_flags);
4250 } else {
4251 ret = osd_set_scan_mode(index);
4252 spin_lock_irqsave(&osd_lock, lock_flags);
4253 if (ret)
4254 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
4255 osd_hw.reg[DISP_GEOMETRY].update_func(index);
4256 osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(index);
4257 osd_hw.reg[OSD_ENABLE].update_func(index);
4258 spin_unlock_irqrestore(&osd_lock, lock_flags);
4259 }
Googler9398cc32022-12-02 17:21:52 +08004260 if (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC &&
4261 osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
Googler9726be62022-12-14 05:53:31 +00004262 u32 output_index = VIU1;
4263 u32 background_w = 0, background_h = 0;
4264
4265 background_w =
4266 osd_hw.free_src_data[index].x_end -
4267 osd_hw.free_src_data[index].x_start + 1;
4268 background_h =
4269 osd_hw.free_src_data[index].y_end -
4270 osd_hw.free_src_data[index].y_start + 1;
4271
4272 output_index = get_output_device_id(index);
4273 osd_hw.disp_info[output_index].background_w =
4274 background_w;
4275 osd_hw.disp_info[output_index].background_h =
4276 background_h;
4277 osd_setting_default_hwc();
4278 }
4279
4280 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004281}
4282
4283void osd_set_free_scale_enable_hw(u32 index, u32 enable)
4284{
Googler9398cc32022-12-02 17:21:52 +08004285 if (osd_hw.free_scale_mode[index] &&
4286 (osd_hw.osd_meson_dev.has_viu2 ?
4287 (index != osd_hw.osd_meson_dev.viu2_index ?
4288 1 : 0) : 1)) {
Googler4f18c0c2022-09-20 17:23:36 +08004289 osd_set_free_scale_enable_mode1(index, enable);
4290 if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
4291 u32 height_dst, height_src;
4292
4293 height_dst = osd_hw.free_dst_data[index].y_end -
4294 osd_hw.free_dst_data[index].y_start + 1;
4295 height_src = osd_hw.free_src_data[index].y_end -
4296 osd_hw.free_src_data[index].y_start + 1;
Googler9726be62022-12-14 05:53:31 +00004297 if (height_dst != height_src &&
4298 osd_hw.free_dst_data[index].y_end <
4299 osd_hw.vinfo_height[VIU1] - 1)
Googler4f18c0c2022-09-20 17:23:36 +08004300 osd_set_dummy_data(index, 0);
4301 else
4302 osd_set_dummy_data(index, 0xff);
4303 }
4304 } else if (enable)
Googler9398cc32022-12-02 17:21:52 +08004305 osd_log_info("osd[%d] %s mode is error %d\n",
4306 index, __func__,
4307 osd_hw.free_scale_mode[index]);
Googler4f18c0c2022-09-20 17:23:36 +08004308}
4309
4310void osd_get_free_scale_enable_hw(u32 index, u32 *free_scale_enable)
4311{
4312 *free_scale_enable = osd_hw.free_scale_enable[index];
4313}
4314
4315void osd_set_free_scale_mode_hw(u32 index, u32 freescale_mode)
4316{
4317 osd_hw.free_scale_mode[index] = freescale_mode;
4318 osd_hw.free_scale_mode_backup[index] = freescale_mode;
4319}
4320
4321void osd_get_free_scale_mode_hw(u32 index, u32 *freescale_mode)
4322{
4323 *freescale_mode = osd_hw.free_scale_mode[index];
4324}
4325
4326void osd_set_4k2k_fb_mode_hw(u32 fb_for_4k2k)
4327{
4328 osd_hw.fb_for_4k2k = fb_for_4k2k;
4329}
4330
4331void osd_get_free_scale_width_hw(u32 index, u32 *free_scale_width)
4332{
4333 *free_scale_width = osd_hw.free_src_data_backup[index].x_end -
4334 osd_hw.free_src_data_backup[index].x_start + 1;
4335}
4336
4337void osd_get_free_scale_height_hw(u32 index, u32 *free_scale_height)
4338{
4339 *free_scale_height = osd_hw.free_src_data_backup[index].y_end -
4340 osd_hw.free_src_data_backup[index].y_start + 1;
4341}
4342
4343void osd_get_free_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
4344{
4345 *x0 = osd_hw.free_src_data_backup[index].x_start;
4346 *y0 = osd_hw.free_src_data_backup[index].y_start;
4347 *x1 = osd_hw.free_src_data_backup[index].x_end;
4348 *y1 = osd_hw.free_src_data_backup[index].y_end;
4349}
4350
4351void osd_set_free_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
4352{
4353 osd_hw.free_src_data[index].x_start = x0;
4354 osd_hw.free_src_data[index].y_start = y0;
4355 osd_hw.free_src_data[index].x_end = x1;
4356 osd_hw.free_src_data[index].y_end = y1;
4357 osd_hw.free_src_data_backup[index].x_start = x0;
4358 osd_hw.free_src_data_backup[index].y_start = y0;
4359 osd_hw.free_src_data_backup[index].x_end = x1;
4360 osd_hw.free_src_data_backup[index].y_end = y1;
4361 osd_hw.src_data[index].x = x0;
4362 osd_hw.src_data[index].y = y0;
4363 osd_hw.src_data[index].w = x1 - x0 + 1;
4364 osd_hw.src_data[index].h = y1 - y0 + 1;
4365}
4366
4367void osd_get_scale_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
4368{
4369 *x0 = osd_hw.scaledata[index].x_start;
4370 *x1 = osd_hw.scaledata[index].x_end;
4371 *y0 = osd_hw.scaledata[index].y_start;
4372 *y1 = osd_hw.scaledata[index].y_end;
4373}
4374
4375void osd_set_scale_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
4376{
4377 osd_hw.scaledata[index].x_start = x0;
4378 osd_hw.scaledata[index].x_end = x1;
4379 osd_hw.scaledata[index].y_start = y0;
4380 osd_hw.scaledata[index].y_end = y1;
4381}
4382
4383void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
4384{
4385 struct vinfo_s *vinfo = NULL;
4386 s32 height;
4387 u32 output_index;
4388
4389 output_index = get_output_device_id(index);
4390 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
Googler9398cc32022-12-02 17:21:52 +08004391 if (output_index == VIU1) {
4392#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +08004393 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08004394#endif
4395 }
Googler4f18c0c2022-09-20 17:23:36 +08004396#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
4397 else if (output_index == VIU2)
4398 vinfo = get_current_vinfo2();
4399#endif
Googler9398cc32022-12-02 17:21:52 +08004400 if (vinfo && vinfo->name && (strcmp(vinfo->name, "invalid") &&
4401 strcmp(vinfo->name, "null"))) {
Googler4f18c0c2022-09-20 17:23:36 +08004402 if (is_interlaced(vinfo)) {
4403 height = osd_hw.free_dst_data_backup[index]
4404 .y_end -
4405 osd_hw.free_dst_data_backup[index]
4406 .y_start + 1;
4407 height *= 2;
4408 *y0 = osd_hw.free_dst_data_backup[index]
4409 .y_start * 2;
4410 *y1 = height + *y0 - 1;
4411 } else {
4412 *y0 = osd_hw.free_dst_data_backup[index]
4413 .y_start;
4414 *y1 = osd_hw.free_dst_data_backup[index]
4415 .y_end;
4416 }
4417 } else {
4418 *y0 = osd_hw.free_dst_data_backup[index].y_start;
4419 *y1 = osd_hw.free_dst_data_backup[index].y_end;
4420 }
4421 *x0 = osd_hw.free_dst_data_backup[index].x_start;
4422 *x1 = osd_hw.free_dst_data_backup[index].x_end;
4423 } else {
4424 *x0 = osd_hw.dst_data[index].x;
4425 *y0 = osd_hw.dst_data[index].y;
4426 *x1 = osd_hw.dst_data[index].x +
4427 osd_hw.dst_data[index].w - 1;
4428 *y1 = osd_hw.dst_data[index].y +
4429 osd_hw.dst_data[index].h - 1;
4430 }
4431}
4432
4433void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
4434{
4435 struct vinfo_s *vinfo = NULL;
4436 s32 temp_y0, temp_y1;
4437 u32 output_index;
Googler9726be62022-12-14 05:53:31 +00004438 u32 height_dst, height_src;
Googler4f18c0c2022-09-20 17:23:36 +08004439
4440 output_index = get_output_device_id(index);
4441 if (output_index == VIU1)
Googler9398cc32022-12-02 17:21:52 +08004442#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +08004443 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08004444#endif
Googler4f18c0c2022-09-20 17:23:36 +08004445#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
4446 else if (output_index == VIU2)
4447 vinfo = get_current_vinfo2();
4448#endif
4449 mutex_lock(&osd_mutex);
Googler9398cc32022-12-02 17:21:52 +08004450 if (vinfo && vinfo->name && (strcmp(vinfo->name, "invalid") &&
4451 strcmp(vinfo->name, "null"))) {
Googler4f18c0c2022-09-20 17:23:36 +08004452 if (is_interlaced(vinfo)) {
4453 temp_y0 = y0 / 2;
4454 temp_y1 = y1 / 2;
4455 } else {
4456 temp_y0 = y0;
4457 temp_y1 = y1;
4458 }
4459 } else {
4460 temp_y0 = y0;
4461 temp_y1 = y1;
4462 }
4463 osd_hw.free_dst_data[index].y_start = temp_y0;
4464 osd_hw.free_dst_data[index].y_end = temp_y1;
4465 osd_hw.free_dst_data[index].x_start = x0;
4466 osd_hw.free_dst_data[index].x_end = x1;
4467 osd_hw.free_dst_data_backup[index].y_start = temp_y0;
4468 osd_hw.free_dst_data_backup[index].y_end = temp_y1;
4469 osd_hw.free_dst_data_backup[index].x_start = x0;
4470 osd_hw.free_dst_data_backup[index].x_end = x1;
4471 if (osd_hw.hw_cursor_en) {
4472 osd_hw.cursor_dispdata[index].x_start = x0;
4473 osd_hw.cursor_dispdata[index].x_end = x1;
4474 osd_hw.cursor_dispdata[index].y_start = temp_y0;
4475 osd_hw.cursor_dispdata[index].y_end = temp_y1;
4476 }
4477 osd_hw.dst_data[index].x = x0;
4478 osd_hw.dst_data[index].y = y0;
4479 osd_hw.dst_data[index].w = x1 - x0 + 1;
4480 osd_hw.dst_data[index].h = y1 - y0 + 1;
Googler9398cc32022-12-02 17:21:52 +08004481 osd_log_dbg2(MODULE_BLEND,
4482 "%s: osd%d orin dst(x:%d y:%d w:%d h:%d)\n",
4483 __func__,
4484 index, osd_hw.dst_data[index].x, osd_hw.dst_data[index].y,
4485 osd_hw.dst_data[index].w, osd_hw.dst_data[index].h);
Googler4f18c0c2022-09-20 17:23:36 +08004486
Googler9726be62022-12-14 05:53:31 +00004487 height_dst = osd_hw.free_dst_data[index].y_end -
4488 osd_hw.free_dst_data[index].y_start + 1;
4489 height_src = osd_hw.free_src_data[index].y_end -
4490 osd_hw.free_src_data[index].y_start + 1;
4491
4492 if (height_dst != height_src)
4493 osd_set_dummy_data(index, 0);
4494 else
4495 osd_set_dummy_data(index, 0xff);
4496
Googler9398cc32022-12-02 17:21:52 +08004497 if (osd_hw.free_dst_data[index].y_end >= osd_hw.vinfo_height[output_index] - 1)
Googler4f18c0c2022-09-20 17:23:36 +08004498 osd_set_dummy_data(index, 0xff);
4499 osd_update_window_axis = true;
Googler9726be62022-12-14 05:53:31 +00004500 osd_update_disp_dst_size(index);
Googler012a81c2022-09-15 14:55:24 +08004501 if (osd_hw.hwc_enable[output_index] &&
Googler9398cc32022-12-02 17:21:52 +08004502 (osd_hw.osd_display_debug[output_index] == OSD_DISP_DEBUG ||
4503 osd_hw.osd_display_fb[output_index]))
4504
Googler4f18c0c2022-09-20 17:23:36 +08004505 osd_setting_blend(output_index);
4506 mutex_unlock(&osd_mutex);
4507}
4508
Googler9398cc32022-12-02 17:21:52 +08004509s32 osd_get_position_from_reg(u32 index,
4510 s32 *src_x_start, s32 *src_x_end,
4511 s32 *src_y_start, s32 *src_y_end,
4512 s32 *dst_x_start, s32 *dst_x_end,
4513 s32 *dst_y_start, s32 *dst_y_end)
Googler4f18c0c2022-09-20 17:23:36 +08004514{
4515 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
4516 u32 data32 = 0x0;
4517
4518 if (index >= OSD_MAX)
4519 return -1;
4520
Googler9398cc32022-12-02 17:21:52 +08004521 if (!src_x_start || !src_x_end || !src_y_start || !src_y_end ||
4522 !dst_y_start || !dst_x_end || !dst_y_start || !dst_y_end)
Googler4f18c0c2022-09-20 17:23:36 +08004523 return -1;
4524
4525 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w1);
4526 *src_x_start = data32 & 0x1fff;
4527 *src_x_end = (data32 >> 16) & 0x1fff;
4528
4529 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w2);
4530 *src_y_start = data32 & 0x1fff;
4531 *src_y_end = (data32 >> 16) & 0x1fff;
4532
4533 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
4534 data32 = osd_reg_read(osd_reg->osd_sc_ctrl0);
4535 if ((data32 & 0xc) == 0xc) {
4536 data32 = osd_reg_read(osd_reg->osd_sco_h_start_end);
4537 *dst_x_end = data32 & 0x1fff;
4538 *dst_x_start = (data32 >> 16) & 0x1fff;
4539
4540 data32 = osd_reg_read(osd_reg->osd_sco_v_start_end);
4541 *dst_y_end = data32 & 0x1fff;
4542 *dst_y_start = (data32 >> 16) & 0x1fff;
4543 } else {
4544 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w3);
4545 *dst_x_start = data32 & 0x1fff;
4546 *dst_x_end = (data32 >> 16) & 0x1fff;
4547
4548 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w4);
4549 *dst_y_start = data32 & 0x1fff;
4550 *dst_y_end = (data32 >> 16) & 0x1fff;
4551 }
4552 } else if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
4553 s32 scaler_index = -1;
4554
4555 osd_reg = &hw_osd_reg_array[0];
4556 data32 = osd_reg_read(osd_reg->osd_sc_ctrl0);
4557
4558 if ((data32 & 3) == 0)
4559 scaler_index = 0;
4560 else if ((data32 & 3) == 1)
4561 scaler_index = 1;
4562
4563 if (((data32 & 0xc) == 0xc) && ((u32)scaler_index == index)) {
4564 data32 = osd_reg_read(osd_reg->osd_sco_h_start_end);
4565 *dst_x_end = data32 & 0x1fff;
4566 *dst_x_start = (data32 >> 16) & 0x1fff;
4567
4568 data32 = osd_reg_read(osd_reg->osd_sco_v_start_end);
4569 *dst_y_end = data32 & 0x1fff;
4570 *dst_y_start = (data32 >> 16) & 0x1fff;
4571 } else {
4572 osd_reg = &hw_osd_reg_array[index];
4573 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w3);
4574 *dst_x_start = data32 & 0x1fff;
4575 *dst_x_end = (data32 >> 16) & 0x1fff;
4576
4577 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w4);
4578 *dst_y_start = data32 & 0x1fff;
4579 *dst_y_end = (data32 >> 16) & 0x1fff;
4580 }
4581 } else if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) {
4582 osd_reg = &hw_osd_reg_array[0];
4583 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w3);
4584 *dst_x_start = data32 & 0x1fff;
4585 *dst_x_end = (data32 >> 16) & 0x1fff;
4586
4587 data32 = osd_reg_read(osd_reg->osd_blk0_cfg_w4);
4588 *dst_y_start = data32 & 0x1fff;
4589 *dst_y_end = (data32 >> 16) & 0x1fff;
4590 }
4591 return 0;
4592}
4593
4594void osd_get_block_windows_hw(u32 index, u32 *windows)
4595{
4596 /*
4597 * memcpy(windows, osd_hw.block_windows[index],
4598 * sizeof(osd_hw.block_windows[index]));
4599 */
4600}
4601
4602void osd_set_block_windows_hw(u32 index, u32 *windows)
4603{
4604 /*
4605 * memcpy(osd_hw.block_windows[index], windows,
4606 * sizeof(osd_hw.block_windows[index]));
4607 */
4608 add_to_update_list(index, DISP_GEOMETRY);
Googler9726be62022-12-14 05:53:31 +00004609 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004610}
4611
4612void osd_get_block_mode_hw(u32 index, u32 *mode)
4613{
4614 *mode = osd_hw.block_mode[index];
4615}
4616
4617void osd_set_block_mode_hw(u32 index, u32 mode)
4618{
Googler9726be62022-12-14 05:53:31 +00004619 /* osd_hw.block_mode[index] = mode; */
4620 add_to_update_list(index, DISP_GEOMETRY);
4621 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004622}
4623
4624void osd_enable_3d_mode_hw(u32 index, u32 enable)
4625{
4626 spin_lock_irqsave(&osd_lock, lock_flags);
4627 osd_hw.mode_3d[index].enable = enable;
4628 spin_unlock_irqrestore(&osd_lock, lock_flags);
4629 if (enable) {
Googler9398cc32022-12-02 17:21:52 +08004630 /* when disable 3d mode ,we should return to standard state. */
Googler4f18c0c2022-09-20 17:23:36 +08004631 osd_hw.mode_3d[index].left_right = OSD_LEFT;
4632 osd_hw.mode_3d[index].l_start = osd_hw.pandata[index].x_start;
4633 osd_hw.mode_3d[index].l_end = (osd_hw.pandata[index].x_end +
4634 osd_hw.pandata[index].x_start) >> 1;
4635 osd_hw.mode_3d[index].r_start = osd_hw.mode_3d[index].l_end + 1;
4636 osd_hw.mode_3d[index].r_end = osd_hw.pandata[index].x_end;
4637 osd_hw.mode_3d[index].origin_scale.h_enable =
4638 osd_hw.scale[index].h_enable;
4639 osd_hw.mode_3d[index].origin_scale.v_enable =
4640 osd_hw.scale[index].v_enable;
4641 osd_set_2x_scale_hw(index, 1, 0);
4642 } else {
Googler9398cc32022-12-02 17:21:52 +08004643 osd_set_2x_scale_hw
4644 (index,
4645 osd_hw.mode_3d[index].origin_scale.h_enable,
4646 osd_hw.mode_3d[index].origin_scale.v_enable);
Googler4f18c0c2022-09-20 17:23:36 +08004647 }
4648}
4649
4650void osd_enable_hw(u32 index, u32 enable)
4651{
4652 int i = 0;
Googler9398cc32022-12-02 17:21:52 +08004653 int count = (pxp_mode == 1) ? 3 : WAIT_AFBC_READY_COUNT;
Googler4f18c0c2022-09-20 17:23:36 +08004654 u32 output_index;
4655
4656 if (index == 0) {
4657 osd_log_info("osd[%d] enable: %d (%s)\n",
Googler9398cc32022-12-02 17:21:52 +08004658 index, enable, current->comm);
Googler4f18c0c2022-09-20 17:23:36 +08004659 } else {
4660 osd_log_info("osd[%d] enable: %d (%s)\n",
Googler9398cc32022-12-02 17:21:52 +08004661 index, enable, current->comm);
Googler4f18c0c2022-09-20 17:23:36 +08004662 }
4663
4664 /* reset viu 31bit ?? */
4665 if (!osd_hw.enable[index] &&
Googler9398cc32022-12-02 17:21:52 +08004666 osd_hw.osd_afbcd[index].enable && enable &&
4667 (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC)) {
Googler4f18c0c2022-09-20 17:23:36 +08004668 spin_lock_irqsave(&osd_lock, lock_flags);
4669 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
4670 osd_reg_write(VIU_SW_RESET, 0x80000000);
4671 osd_reg_write(VIU_SW_RESET, 0);
4672 }
Googler4f18c0c2022-09-20 17:23:36 +08004673
4674 spin_unlock_irqrestore(&osd_lock, lock_flags);
4675 osd_afbc_dec_enable = 0;
4676 add_to_update_list(index, OSD_COLOR_MODE);
4677 add_to_update_list(index, OSD_GBL_ALPHA);
4678 add_to_update_list(index, DISP_GEOMETRY);
Googler9726be62022-12-14 05:53:31 +00004679 osd_wait_vsync_hw(index);
4680
4681 while ((index == 0) && osd_hw.osd_afbcd[index].enable &&
Googler9398cc32022-12-02 17:21:52 +08004682 (osd_hw.osd_afbcd[index].phy_addr == 0) &&
4683 enable && (i < count)) {
Googler9726be62022-12-14 05:53:31 +00004684 osd_wait_vsync_hw(index);
4685 i++;
4686 }
4687 if (i > 0)
4688 osd_log_info("osd[%d]: wait %d vsync first buffer ready.\n",
Googler9398cc32022-12-02 17:21:52 +08004689 index, i);
Googler4f18c0c2022-09-20 17:23:36 +08004690 }
4691
4692 osd_hw.enable[index] = enable;
4693 output_index = get_output_device_id(index);
Googler9726be62022-12-14 05:53:31 +00004694 osd_update_disp_src_size(index);
4695 osd_update_disp_dst_size(index);
Googler4f18c0c2022-09-20 17:23:36 +08004696 if (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC) {
Googler9398cc32022-12-02 17:21:52 +08004697 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE)
4698 osd_setting_default_hwc();
Googler4f18c0c2022-09-20 17:23:36 +08004699 add_to_update_list(index, OSD_ENABLE);
Googler9726be62022-12-14 05:53:31 +00004700 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004701 } else if (osd_hw.hwc_enable[output_index] &&
Googler9398cc32022-12-02 17:21:52 +08004702 (osd_hw.osd_display_debug[output_index] == OSD_DISP_DEBUG ||
4703 osd_hw.osd_display_fb[output_index])) {
Googler4f18c0c2022-09-20 17:23:36 +08004704 osd_setting_blend(output_index);
Googler9398cc32022-12-02 17:21:52 +08004705 }
Googler4f18c0c2022-09-20 17:23:36 +08004706}
4707
4708void osd_set_2x_scale_hw(u32 index, u16 h_scale_enable, u16 v_scale_enable)
4709{
4710 osd_log_info("osd[%d] set scale, h_scale: %s, v_scale: %s\n",
4711 index, h_scale_enable ? "ENABLE" : "DISABLE",
4712 v_scale_enable ? "ENABLE" : "DISABLE");
4713 osd_log_info("osd[%d].scaledata: %d %d %d %d\n",
4714 index,
4715 osd_hw.scaledata[index].x_start,
4716 osd_hw.scaledata[index].x_end,
4717 osd_hw.scaledata[index].y_start,
4718 osd_hw.scaledata[index].y_end);
4719 osd_log_info("osd[%d].pandata: %d %d %d %d\n",
4720 index,
4721 osd_hw.pandata[index].x_start,
4722 osd_hw.pandata[index].x_end,
4723 osd_hw.pandata[index].y_start,
4724 osd_hw.pandata[index].y_end);
4725 osd_hw.scale[index].h_enable = h_scale_enable;
4726 osd_hw.scale[index].v_enable = v_scale_enable;
4727 spin_lock_irqsave(&osd_lock, lock_flags);
4728 osd_hw.reg[DISP_SCALE_ENABLE].update_func(index);
4729 osd_hw.reg[DISP_GEOMETRY].update_func(index);
4730 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +00004731 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004732}
4733
4734void osd_get_flush_rate_hw(u32 index, u32 *break_rate)
4735{
4736 const struct vinfo_s *vinfo = NULL;
4737 u32 output_index;
4738
4739 output_index = get_output_device_id(index);
4740 if (output_index == VIU1)
Googler9398cc32022-12-02 17:21:52 +08004741#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +08004742 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08004743#endif
Googler4f18c0c2022-09-20 17:23:36 +08004744#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
4745 else if (output_index == VIU2)
4746 vinfo = get_current_vinfo2();
4747#endif
4748 if (!vinfo)
4749 return;
4750 *break_rate = vinfo->sync_duration_num / vinfo->sync_duration_den;
4751}
4752
4753void osd_set_antiflicker_hw(u32 index, struct vinfo_s *vinfo, u32 yres)
4754{
4755#ifdef NEED_ANTIFLICKER
4756 bool osd_need_antiflicker = false;
4757
4758 if (is_interlaced(vinfo))
4759 osd_need_antiflicker = false;
4760 else
4761 osd_need_antiflicker = true;
4762 if (osd_need_antiflicker) {
4763 osd_hw.antiflicker_mode = 1;
4764 osd_antiflicker_task_start();
4765 osd_antiflicker_enable(1);
4766 osd_antiflicker_update_pan(osd_hw.pandata[index].y_start, yres);
4767 }
4768#else
4769 if (osd_hw.antiflicker_mode)
4770 osd_antiflicker_task_stop();
4771 osd_hw.antiflicker_mode = 0;
4772#endif
4773}
4774
4775void osd_get_antiflicker_hw(u32 index, u32 *on_off)
4776{
4777 *on_off = osd_hw.antiflicker_mode;
4778}
4779
4780/* Todo: how to expand to 3 osd */
4781void osd_clone_pan(u32 index, u32 yoffset, int debug_flag)
4782{
4783 s32 offset = 0;
4784 u32 index_buffer = 0;
4785 s32 osd0_buffer_number = 0;
4786 s32 height_osd1 = 0;
4787
4788 if (yoffset != 0) {
4789 index_buffer = osd_hw.fb_gem[index].height / yoffset;
4790 if (index_buffer == 3)
4791 osd0_buffer_number = 1;
4792 else if (index_buffer == 1)
4793 osd0_buffer_number = 2;
Googler9398cc32022-12-02 17:21:52 +08004794 } else {
Googler4f18c0c2022-09-20 17:23:36 +08004795 osd0_buffer_number = 0;
Googler9398cc32022-12-02 17:21:52 +08004796 }
Googler4f18c0c2022-09-20 17:23:36 +08004797 osd_clone_get_virtual_yres(&height_osd1);
4798 if (osd_hw.clone[index]) {
4799 offset = osd0_buffer_number * height_osd1;
4800 osd_hw.pandata[OSD2].y_start = offset;
4801 osd_hw.pandata[OSD2].y_end = offset + height_osd1 - 1;
4802 if (osd_hw.angle[OSD2]) {
4803 if (debug_flag)
Googler9398cc32022-12-02 17:21:52 +08004804 osd_log_dbg(MODULE_BASE, "%s start when enable clone\n",
4805 __func__);
Googler4f18c0c2022-09-20 17:23:36 +08004806 osd_clone_update_pan(osd0_buffer_number);
4807 }
4808 add_to_update_list(OSD2, DISP_GEOMETRY);
4809 }
4810}
4811
4812/* Todo: how to expand to 3 osd */
4813void osd_set_angle_hw(u32 index, u32 angle, u32 virtual_osd1_yres,
4814 u32 virtual_osd2_yres)
4815{
4816#ifndef OSD_GE2D_CLONE_SUPPORT
4817 osd_log_err("++ osd_clone depends on GE2D module!\n");
4818 return;
4819#endif
4820 if (angle > 4) {
4821 osd_log_err("++ invalid angle: %d\n", angle);
4822 return;
4823 }
4824 osd_log_info("++ virtual_osd1_yres is %d, virtual_osd2_yres is %d!\n",
4825 virtual_osd1_yres, virtual_osd2_yres);
4826 osd_clone_set_virtual_yres(virtual_osd1_yres, virtual_osd2_yres);
4827 if (osd_hw.clone[index] == 0) {
4828 osd_log_info("++ set osd[%d]->angle: %d->%d\n",
Googler9398cc32022-12-02 17:21:52 +08004829 index, osd_hw.angle[index], angle);
Googler4f18c0c2022-09-20 17:23:36 +08004830 osd_clone_set_angle(angle);
4831 osd_hw.angle[index] = angle;
4832 } else if (!((osd_hw.angle[index] == 0) || (angle == 0))) {
4833 osd_log_info("++ set osd[%d]->angle: %d->%d\n",
Googler9398cc32022-12-02 17:21:52 +08004834 index, osd_hw.angle[index], angle);
Googler4f18c0c2022-09-20 17:23:36 +08004835 osd_clone_set_angle(angle);
4836 osd_hw.angle[index] = angle;
4837 osd_clone_pan(index, osd_hw.pandata[OSD1].y_start, 1);
4838 }
4839}
4840
4841void osd_get_angle_hw(u32 index, u32 *angle)
4842{
4843 *angle = osd_hw.angle[index];
4844}
4845
4846void osd_set_clone_hw(u32 index, u32 clone)
4847{
4848 int ret = -1;
4849
4850 osd_log_info("++ set osd[%d]->clone: %d->%d\n",
Googler9398cc32022-12-02 17:21:52 +08004851 index, osd_hw.clone[index], clone);
Googler4f18c0c2022-09-20 17:23:36 +08004852 osd_hw.clone[index] = clone;
4853 if (osd_hw.clone[index]) {
4854 if (osd_hw.angle[index]) {
4855 osd_hw.color_info[index] = osd_hw.color_info[OSD1];
4856 osd_hw.color_backup[index] = osd_hw.color_info[OSD1];
4857 ret = osd_clone_task_start();
4858 if (ret)
4859 osd_clone_pan(index,
Googler9398cc32022-12-02 17:21:52 +08004860 osd_hw.pandata[OSD1].y_start, 1);
Googler4f18c0c2022-09-20 17:23:36 +08004861 else
4862 osd_log_err("++ start clone error\n");
4863 }
4864 } else {
4865 if (osd_hw.angle[index])
4866 osd_clone_task_stop();
4867 }
4868 add_to_update_list(index, OSD_COLOR_MODE);
4869}
4870
4871void osd_set_update_pan_hw(u32 index)
4872{
4873 osd_clone_pan(index, osd_hw.pandata[OSD1].y_start, 1);
4874}
4875
4876void osd_get_clone_hw(u32 index, u32 *clone)
4877{
4878 *clone = osd_hw.clone[index];
4879}
4880
4881void osd_set_reverse_hw(u32 index, u32 reverse, u32 update)
4882{
4883 char *str[4] = {"NONE", "ALL", "X_REV", "Y_REV"};
4884
4885 osd_hw.osd_reverse[index] = reverse;
4886 pr_info("set osd%d reverse as %s\n", index, str[reverse]);
4887 if (update) {
4888 add_to_update_list(index, DISP_OSD_REVERSE);
Googler9726be62022-12-14 05:53:31 +00004889 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004890 }
4891}
4892
4893void osd_get_reverse_hw(u32 index, u32 *reverse)
4894{
4895 *reverse = osd_hw.osd_reverse[index];
4896}
4897
4898/* Todo: how to do with uboot logo */
Googler9398cc32022-12-02 17:21:52 +08004899void osd_switch_free_scale(u32 pre_index, u32 pre_enable,
4900 u32 pre_scale, u32 next_index,
4901 u32 next_enable, u32 next_scale)
Googler4f18c0c2022-09-20 17:23:36 +08004902{
4903 unsigned int h_enable = 0;
4904 unsigned int v_enable = 0;
4905 int i = 0;
Googler9398cc32022-12-02 17:21:52 +08004906 int count = (pxp_mode == 1) ? 3 : WAIT_AFBC_READY_COUNT;
Googler4f18c0c2022-09-20 17:23:36 +08004907
4908 osd_log_info("osd[%d] enable: %d scale:0x%x (%s)\n",
Googler9398cc32022-12-02 17:21:52 +08004909 pre_index, pre_enable, pre_scale, current->comm);
Googler4f18c0c2022-09-20 17:23:36 +08004910 osd_log_info("osd[%d] enable: %d scale:0x%x (%s)\n",
Googler9398cc32022-12-02 17:21:52 +08004911 next_index, next_enable, next_scale, current->comm);
4912 if (osd_hw.free_scale_mode[pre_index] ||
4913 osd_hw.free_scale_mode[next_index]) {
Googler4f18c0c2022-09-20 17:23:36 +08004914 if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
Googler9398cc32022-12-02 17:21:52 +08004915 while (next_index == OSD1 &&
4916 osd_hw.osd_afbcd[next_index].enable &&
4917 (osd_hw.osd_afbcd[next_index].phy_addr == 0) &&
4918 next_enable && (i < count)) {
Googler9726be62022-12-14 05:53:31 +00004919 osd_wait_vsync_hw(OSD1);
Googler4f18c0c2022-09-20 17:23:36 +08004920 i++;
Googler9726be62022-12-14 05:53:31 +00004921 }
4922 if (i > 0)
4923 osd_log_info("osd[%d]: wait %d vsync first buffer ready.\n",
Googler9398cc32022-12-02 17:21:52 +08004924 next_index, i);
Googler4f18c0c2022-09-20 17:23:36 +08004925 }
4926 if (pre_index != next_index) {
4927 h_enable = (pre_scale & 0xffff0000 ? 1 : 0);
4928 v_enable = (pre_scale & 0xffff ? 1 : 0);
4929 osd_hw.free_scale[pre_index].h_enable = h_enable;
4930 osd_hw.free_scale[pre_index].v_enable = v_enable;
4931 osd_hw.free_scale_enable[pre_index] = pre_scale;
4932 osd_hw.free_scale_backup[pre_index].h_enable = h_enable;
4933 osd_hw.free_scale_backup[pre_index].v_enable = v_enable;
4934 osd_hw.free_scale_enable_backup[pre_index] = pre_scale;
4935 osd_hw.enable[pre_index] = pre_enable;
4936 }
4937 h_enable = (next_scale & 0xffff0000 ? 1 : 0);
4938 v_enable = (next_scale & 0xffff ? 1 : 0);
4939 osd_hw.free_scale[next_index].h_enable = h_enable;
4940 osd_hw.free_scale[next_index].v_enable = v_enable;
4941 osd_hw.free_scale_enable[next_index] = next_scale;
4942 osd_hw.free_scale_backup[next_index].h_enable = h_enable;
4943 osd_hw.free_scale_backup[next_index].v_enable = v_enable;
4944 osd_hw.free_scale_enable_backup[next_index] = next_scale;
4945 osd_hw.enable[next_index] = next_enable;
4946
4947 osd_set_scan_mode(next_index);
4948 spin_lock_irqsave(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +08004949 if (next_index == OSD1 &&
4950 osd_hw.osd_afbcd[next_index].enable &&
4951 next_enable) {
Googler9726be62022-12-14 05:53:31 +00004952 if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
4953 osd_reg_write(VIU_SW_RESET, 0x80000000);
4954 osd_reg_write(VIU_SW_RESET, 0);
4955 }
Googler4f18c0c2022-09-20 17:23:36 +08004956 osd_afbc_dec_enable = 0;
4957 osd_hw.reg[OSD_GBL_ALPHA].update_func(next_index);
4958 }
4959 if (pre_index != next_index) {
4960 osd_hw.reg[OSD_COLOR_MODE].update_func(pre_index);
4961 if (pre_scale)
Googler9398cc32022-12-02 17:21:52 +08004962 osd_hw.reg[OSD_FREESCALE_COEF]
4963 .update_func(pre_index);
Googler4f18c0c2022-09-20 17:23:36 +08004964 osd_hw.reg[DISP_GEOMETRY].update_func(pre_index);
Googler9398cc32022-12-02 17:21:52 +08004965 osd_hw.reg[DISP_FREESCALE_ENABLE]
4966 .update_func(pre_index);
Googler4f18c0c2022-09-20 17:23:36 +08004967 osd_hw.reg[OSD_ENABLE].update_func(pre_index);
Googler0109c452022-10-13 17:50:39 +08004968
Googler9726be62022-12-14 05:53:31 +00004969 osd_hw.reg[OSD_COLOR_MODE].update_func(next_index);
4970 if (next_scale)
Googler9398cc32022-12-02 17:21:52 +08004971 osd_hw.reg[OSD_FREESCALE_COEF]
4972 .update_func(next_index);
Googler9726be62022-12-14 05:53:31 +00004973 osd_hw.reg[DISP_GEOMETRY].update_func(next_index);
Googler9398cc32022-12-02 17:21:52 +08004974 osd_hw.reg[DISP_FREESCALE_ENABLE]
4975 .update_func(next_index);
Googler9726be62022-12-14 05:53:31 +00004976 osd_hw.reg[OSD_ENABLE].update_func(next_index);
4977 }
Googler4f18c0c2022-09-20 17:23:36 +08004978 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +00004979 osd_wait_vsync_hw(next_index);
Googler4f18c0c2022-09-20 17:23:36 +08004980 } else {
4981 if (pre_index != next_index)
4982 osd_enable_hw(pre_index, pre_enable);
4983 osd_enable_hw(next_index, next_enable);
4984 }
4985}
4986
4987void osd_get_urgent(u32 index, u32 *urgent)
4988{
4989 *urgent = osd_hw.urgent[index];
4990}
4991
4992void osd_set_urgent(u32 index, u32 urgent)
4993{
4994 osd_hw.urgent[index] = urgent;
4995 add_to_update_list(index, OSD_FIFO);
Googler9726be62022-12-14 05:53:31 +00004996 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08004997}
4998
Googler9398cc32022-12-02 17:21:52 +08004999void osd_get_deband(u32 index, u32 *osd_deband_enable)
Googler4f18c0c2022-09-20 17:23:36 +08005000{
Googler9398cc32022-12-02 17:21:52 +08005001 *osd_deband_enable = osd_hw.osd_deband_enable[index];
Googler4f18c0c2022-09-20 17:23:36 +08005002}
5003
Googler9398cc32022-12-02 17:21:52 +08005004void osd_set_deband(u32 index, u32 osd_deband_enable)
Googler4f18c0c2022-09-20 17:23:36 +08005005{
5006 u32 data32;
Googler9398cc32022-12-02 17:21:52 +08005007 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
5008 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08005009
5010 if (osd_hw.osd_meson_dev.has_deband) {
Googler9398cc32022-12-02 17:21:52 +08005011 if (osd_hw.free_scale_enable[index]) {
5012 osd_hw.osd_deband_enable[index] = osd_deband_enable;
Googler4f18c0c2022-09-20 17:23:36 +08005013 spin_lock_irqsave(&osd_lock, lock_flags);
5014
Googler9398cc32022-12-02 17:21:52 +08005015 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
5016 (osd_reg->osd_db_flt_ctrl);
Googler4f18c0c2022-09-20 17:23:36 +08005017 if (osd_deband_enable) {
5018 /* Bit 23 debanding registers of side
5019 * lines, [0] for luma
5020 * Bit 22 debanding registers of side
5021 * lines, [1] for chroma
5022 * Bit 5debanding registers,for luma
5023 * Bit 4debanding registers,for chroma
5024 */
5025 data32 |= 3 << 4;
5026 data32 |= 3 << 22;
5027 } else {
5028 data32 |= 0 << 4;
5029 data32 |= 0 << 22;
5030 }
Googler9398cc32022-12-02 17:21:52 +08005031 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
5032 (osd_reg->osd_db_flt_ctrl, data32);
Googler4f18c0c2022-09-20 17:23:36 +08005033 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +08005034 osd_wait_vsync_hw_viux(output_index);
Googler4f18c0c2022-09-20 17:23:36 +08005035 }
5036 }
5037}
5038
Googler4f18c0c2022-09-20 17:23:36 +08005039void osd_get_fps(u32 index, u32 *osd_fps)
5040{
5041 u32 output_index;
5042
5043 output_index = get_output_device_id(index);
5044 *osd_fps = osd_hw.osd_fps[output_index];
Googler4f18c0c2022-09-20 17:23:36 +08005045}
5046
5047void osd_set_fps(u32 index, u32 osd_fps_start)
5048{
5049 static int stime, etime;
5050 u32 output_index;
5051
5052 output_index = get_output_device_id(index);
5053 osd_hw.osd_fps_start[output_index] = osd_fps_start;
5054 if (osd_fps_start) {
5055 /* start to calc fps */
5056 stime = ktime_to_us(ktime_get());
5057 osd_hw.osd_fps[output_index] = 0;
5058 } else {
5059 /* stop to calc fps */
5060 etime = ktime_to_us(ktime_get());
5061 osd_hw.osd_fps[output_index] =
5062 (osd_hw.osd_fps[output_index] * 1000000)
5063 / (etime - stime);
5064 osd_log_info("osd fps:=%d\n", osd_hw.osd_fps[output_index]);
5065 }
5066}
5067
Googler9726be62022-12-14 05:53:31 +00005068void osd_get_display_debug(u32 index, u32 *osd_display_debug_enable)
Googler4f18c0c2022-09-20 17:23:36 +08005069{
Googler9726be62022-12-14 05:53:31 +00005070 u32 output_index;
5071
5072 output_index = get_output_device_id(index);
5073 *osd_display_debug_enable = osd_hw.osd_display_debug[output_index];
Googler4f18c0c2022-09-20 17:23:36 +08005074}
5075
Googler9726be62022-12-14 05:53:31 +00005076void osd_set_display_debug(u32 index, u32 osd_display_debug_enable)
Googler4f18c0c2022-09-20 17:23:36 +08005077{
Googler9726be62022-12-14 05:53:31 +00005078 u32 output_index;
5079
5080 output_index = get_output_device_id(index);
5081 osd_hw.osd_display_debug[output_index] = osd_display_debug_enable;
5082}
5083
5084void osd_get_display_fb(u32 index, u32 *osd_display_fb)
5085{
5086 u32 output_index;
5087
5088 output_index = get_output_device_id(index);
5089 *osd_display_fb = osd_hw.osd_display_fb[output_index];
5090}
5091
5092void osd_set_display_fb(u32 index, u32 osd_display_fb)
5093{
5094 u32 output_index;
5095
5096 output_index = get_output_device_id(index);
5097 osd_hw.osd_display_fb[output_index] = osd_display_fb;
Googler38bda472022-08-19 10:07:08 -07005098}
5099
Googler9398cc32022-12-02 17:21:52 +08005100void osd_get_sc_depend(u32 *osd_sc_depend)
5101{
5102 *osd_sc_depend = osd_hw.osd_meson_dev.osd0_sc_independ;
5103}
5104
5105void osd_set_sc_depend(u32 osd_sc_depend)
5106{
5107 osd_hw.osd_meson_dev.osd0_sc_independ = osd_sc_depend;
5108}
5109
Googler4f18c0c2022-09-20 17:23:36 +08005110void osd_get_background_size(u32 index, struct display_flip_info_s *disp_info)
5111{
5112 u32 output_index;
5113
5114 output_index = get_output_device_id(index);
5115 memcpy(disp_info, &osd_hw.disp_info[output_index],
5116 sizeof(struct display_flip_info_s));
5117}
5118
5119void osd_set_background_size(u32 index, struct display_flip_info_s *disp_info)
5120{
5121 u32 output_index;
5122
5123 output_index = get_output_device_id(index);
5124 memcpy(&osd_hw.disp_info[output_index], disp_info,
5125 sizeof(struct display_flip_info_s));
5126}
5127
5128void osd_get_hdr_used(u32 *val)
5129{
5130 *val = osd_hw.hdr_used;
5131}
5132
5133void osd_set_hdr_used(u32 val)
5134{
5135 osd_hw.hdr_used = val;
5136}
5137
5138void osd_get_afbc_format(u32 index, u32 *format, u32 *inter_format)
5139{
5140 *format = osd_hw.osd_afbcd[index].format;
5141 *inter_format = osd_hw.osd_afbcd[index].inter_format;
5142}
5143
5144void osd_set_afbc_format(u32 index, u32 format, u32 inter_format)
5145{
5146 osd_hw.osd_afbcd[index].format = format;
5147 osd_hw.osd_afbcd[index].inter_format = inter_format;
5148}
5149
5150void osd_get_hwc_enable(u32 index, u32 *hwc_enable)
5151{
5152 u32 output_index;
5153
5154 output_index = get_output_device_id(index);
5155 *hwc_enable = osd_hw.hwc_enable[output_index];
5156}
5157
5158void osd_set_hwc_enable(u32 index, u32 hwc_enable)
5159{
5160 u32 output_index;
5161
5162 output_index = get_output_device_id(index);
5163 osd_hw.hwc_enable[output_index] = hwc_enable;
5164 /* setting default hwc path */
5165 if (!hwc_enable)
5166 osd_setting_blend(OSD1);
5167}
5168
5169void osd_do_hwc(u32 index)
5170{
5171 u32 output_index;
5172
5173 output_index = get_output_device_id(index);
5174 osd_setting_blend(output_index);
5175}
5176
5177static void osd_set_two_ports(bool set)
5178{
5179 static u32 data32[2];
5180
Googler9398cc32022-12-02 17:21:52 +08005181 if (osd_dev_hw.t7_display) {
5182 if (osd_hw.osd_meson_dev.cpu_id ==
5183 __MESON_CPU_MAJOR_ID_T3) {
5184 /* set osd, video two port */
5185 if (set) {
5186 /*mali afbcd,dolby0, osd1-4 etc->VPU0*/
5187 /*aisr reshape, vd1, vd2, tcon p1 read->VPU2*/
5188 osd_reg_write(VPP_RDARB_MODE, 0x10c00000);
5189 osd_reg_write(VPU_RDARB_MODE_L2C1, 0x920000);
5190 } else {
5191 osd_reg_write(VPP_RDARB_MODE, 0xaa0000);
5192 osd_reg_write(VPU_RDARB_MODE_L2C1, 0x900000);
5193 }
5194 }
5195 return;
5196 }
5197 /* set osd, video two port */
Googler4f18c0c2022-09-20 17:23:36 +08005198 if (set) {
5199 data32[0] = osd_reg_read(VPP_RDARB_MODE);
5200 data32[1] = osd_reg_read(VPU_RDARB_MODE_L2C1);
5201 osd_reg_set_bits(VPP_RDARB_MODE, 2, 20, 8);
5202 osd_reg_set_bits(VPU_RDARB_MODE_L2C1, 2, 16, 8);
5203 } else {
5204 osd_reg_write(VPP_RDARB_MODE, data32[0]);
5205 osd_reg_write(VPU_RDARB_MODE_L2C1, data32[1]);
5206 }
5207}
5208
5209static void osd_set_basic_urgent(bool set)
5210{
5211 if (set)
5212 osd_reg_write(0x27c2, 0xffff);
5213 else
5214 osd_reg_write(0x27c2, 0x0);
5215}
5216
5217void osd_get_urgent_info(u32 *ports, u32 *basic_urgent)
5218{
5219 *basic_urgent = osd_hw.basic_urgent;
5220 *ports = osd_hw.two_ports;
5221}
5222
5223void osd_set_urgent_info(u32 ports, u32 basic_urgent)
5224{
5225 osd_hw.basic_urgent = basic_urgent;
5226 osd_hw.two_ports = ports;
5227 osd_set_basic_urgent(osd_hw.basic_urgent);
5228 osd_set_two_ports(osd_hw.two_ports);
5229}
5230
5231void osd_set_single_step_mode(u32 index, u32 osd_single_step_mode)
5232{
5233 u32 output_index;
5234
5235 output_index = get_output_device_id(index);
5236 if (output_index != VIU1)
5237 return;
5238 osd_hw.osd_debug.osd_single_step_mode = osd_single_step_mode;
Googler9398cc32022-12-02 17:21:52 +08005239 if (osd_hw.osd_debug.wait_fence_release &&
5240 osd_hw.osd_debug.osd_single_step_mode == 0) {
Googler4f18c0c2022-09-20 17:23:36 +08005241#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
5242 osd_timeline_increase(output_index);
5243#endif
Googler9398cc32022-12-02 17:21:52 +08005244 osd_hw.osd_debug.wait_fence_release = 0;
Googler4f18c0c2022-09-20 17:23:36 +08005245 }
Googler4f18c0c2022-09-20 17:23:36 +08005246}
5247
5248void osd_set_single_step(u32 index, u32 osd_single_step)
5249{
5250 u32 output_index;
5251
5252 output_index = get_output_device_id(index);
5253 if (output_index != VIU1)
5254 return;
5255 osd_hw.osd_debug.osd_single_step = osd_single_step;
Googler9398cc32022-12-02 17:21:52 +08005256 if (osd_hw.osd_debug.wait_fence_release &&
5257 osd_hw.osd_debug.osd_single_step > 0) {
Googler4f18c0c2022-09-20 17:23:36 +08005258#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
5259 osd_timeline_increase(output_index);
5260#endif
Googler9398cc32022-12-02 17:21:52 +08005261 osd_hw.osd_debug.wait_fence_release = 0;
Googler4f18c0c2022-09-20 17:23:36 +08005262 }
5263}
5264
5265void osd_get_rotate(u32 index, u32 *osd_rotate)
5266{
5267 *osd_rotate = osd_hw.osd_rotate[index];
5268}
5269
5270void osd_set_rotate(u32 index, u32 osd_rotate)
5271{
5272 if (index != osd_hw.osd_meson_dev.viu2_index)
5273 osd_log_err("osd%d not support rotate\n", index);
5274 osd_hw.osd_rotate[index] = osd_rotate;
5275 add_to_update_list(index, DISP_OSD_ROTATE);
Googler9726be62022-12-14 05:53:31 +00005276 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08005277}
5278
Googler9398cc32022-12-02 17:21:52 +08005279void osd_get_afbc_err_cnt(u32 index, u32 *err_cnt)
Googler4f18c0c2022-09-20 17:23:36 +08005280{
Googler9398cc32022-12-02 17:21:52 +08005281 *err_cnt = osd_hw.afbc_err_cnt[index];
Googler4f18c0c2022-09-20 17:23:36 +08005282}
5283
5284void osd_get_dimm_info(u32 index, u32 *osd_dimm_layer, u32 *osd_dimm_color)
5285{
5286 *osd_dimm_layer = osd_hw.dim_layer[index];
5287 *osd_dimm_color = osd_hw.dim_color[index];
5288}
5289
5290void osd_set_dimm_info(u32 index, u32 osd_dimm_layer, u32 osd_dimm_color)
5291{
5292 osd_hw.dim_layer[index] = osd_dimm_layer;
5293 osd_hw.dim_color[index] = osd_dimm_color;
5294}
5295
Googler9726be62022-12-14 05:53:31 +00005296u32 osd_get_hold_line(u32 index)
5297{
5298 unsigned int data32 = 0, val = 0;
Googler9398cc32022-12-02 17:21:52 +08005299 u32 output_index = get_output_device_id(index);
Googler9726be62022-12-14 05:53:31 +00005300
5301 if (osd_hw.powered[index]) {
Googler9398cc32022-12-02 17:21:52 +08005302 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
Googler9726be62022-12-14 05:53:31 +00005303 (hw_osd_reg_array[index].osd_fifo_ctrl_stat);
5304 val = (data32 >> 5) & 0x1f;
5305 }
5306 return val;
5307}
5308
5309void osd_set_hold_line(u32 index, int hold_line)
5310{
5311 unsigned int data32 = 0, val = 0;
Googler9398cc32022-12-02 17:21:52 +08005312 u32 output_index = get_output_device_id(index);
Googler9726be62022-12-14 05:53:31 +00005313
5314 if (osd_hw.powered[index]) {
Googler9398cc32022-12-02 17:21:52 +08005315 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
Googler9726be62022-12-14 05:53:31 +00005316 (hw_osd_reg_array[index].osd_fifo_ctrl_stat);
5317 val = (data32 >> 5) & 0x1f;
5318 if (val != hold_line) {
Googler9398cc32022-12-02 17:21:52 +08005319 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
Googler9726be62022-12-14 05:53:31 +00005320 (hw_osd_reg_array[index].osd_fifo_ctrl_stat,
5321 hold_line & 0x1f, 5, 5);
5322 }
5323 }
5324}
5325
Googler4f18c0c2022-09-20 17:23:36 +08005326int osd_get_capbility(u32 index)
5327{
5328 u32 capbility = 0;
Googler9726be62022-12-14 05:53:31 +00005329 u32 afbc = osd_hw.osd_meson_dev.afbc_type;
Googler4f18c0c2022-09-20 17:23:36 +08005330
5331 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
Googler9398cc32022-12-02 17:21:52 +08005332 u32 output_index = get_output_device_id(index);
5333 u32 vpp_top = 0;
5334
5335 if (output_index == VIU2)
5336 vpp_top = OSD_VIU2;
5337 else if (output_index == VIU3)
5338 vpp_top = OSD_VIU3;
5339 else
5340 vpp_top = OSD_VIU1 | OSD_ZORDER;
5341
Googler4f18c0c2022-09-20 17:23:36 +08005342 if (index == OSD1)
5343 capbility |= OSD_LAYER_ENABLE | OSD_FREESCALE
Googler9398cc32022-12-02 17:21:52 +08005344 | OSD_UBOOT_LOGO | vpp_top
Googler9726be62022-12-14 05:53:31 +00005345 | OSD_PRIMARY | (afbc ? OSD_AFBC : 0);
Googler4f18c0c2022-09-20 17:23:36 +08005346 else if (index < osd_hw.osd_meson_dev.viu1_osd_count)
Googler9398cc32022-12-02 17:21:52 +08005347 capbility |= OSD_LAYER_ENABLE |
5348 vpp_top |
5349 (osd_hw.pps_support[index] ?
5350 OSD_FREESCALE : 0) |
5351 ((afbc && osd_hw.afbc_support[index]) ?
5352 OSD_AFBC : 0);
Googler4f18c0c2022-09-20 17:23:36 +08005353 else if (index == osd_hw.osd_meson_dev.viu2_index)
Googler9398cc32022-12-02 17:21:52 +08005354 capbility |= OSD_LAYER_ENABLE | vpp_top;
Googler4f18c0c2022-09-20 17:23:36 +08005355 } else if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
5356 if (index == OSD1)
5357 capbility |= OSD_LAYER_ENABLE | OSD_FREESCALE
Googler9726be62022-12-14 05:53:31 +00005358 | OSD_VIU1 | (afbc ? OSD_AFBC : 0);
Googler4f18c0c2022-09-20 17:23:36 +08005359 else if (index == OSD2)
5360 capbility |= OSD_LAYER_ENABLE |
5361 OSD_HW_CURSOR | OSD_FREESCALE
Googler9726be62022-12-14 05:53:31 +00005362 | OSD_UBOOT_LOGO | OSD_VIU1 |
5363 (afbc ? OSD_AFBC : 0);
Googler4f18c0c2022-09-20 17:23:36 +08005364 }
Googler9726be62022-12-14 05:53:31 +00005365
Googler4f18c0c2022-09-20 17:23:36 +08005366 return capbility;
5367}
5368
Googler9398cc32022-12-02 17:21:52 +08005369static void save_blend_reg(struct hw_osd_blending_s *blending)
Googler4f18c0c2022-09-20 17:23:36 +08005370{
5371 struct osd_debug_backup_s *osd_backup;
5372 int count = osd_hw.osd_debug.backup_count;
5373
5374 osd_backup = &osd_hw.osd_debug.osd_backup[count];
Googler9398cc32022-12-02 17:21:52 +08005375 memcpy(&osd_backup->osd_blend_reg,
5376 &blending->osd_blend_reg,
5377 sizeof(struct osd_blend_reg_s));
5378 memcpy(&osd_backup->vpp0_blend_reg,
5379 &blending->vpp0_blend_reg,
5380 sizeof(struct vpp0_blend_reg_s));
Googler4f18c0c2022-09-20 17:23:36 +08005381 osd_hw.osd_debug.backup_count++;
5382 if (osd_hw.osd_debug.backup_count >= OSD_BACKUP_COUNT)
5383 osd_hw.osd_debug.backup_count = 0;
5384}
5385
5386static void osd_info_output(int count)
5387{
5388 struct osd_debug_backup_s *osd_backup;
Googler9398cc32022-12-02 17:21:52 +08005389 struct osd_blend_reg_s *osd_blend_reg;
5390 struct vpp0_blend_reg_s *vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08005391 int index;
5392 u32 value;
5393
5394 osd_backup = &osd_hw.osd_debug.osd_backup[count];
5395 osd_log_info("|index|enable|ext_addr|order|blend_mode|plane_alpha|dim_layer|dim_color|src axis|dst axis\n");
5396 for (index = 0; index < HW_OSD_COUNT; index++) {
5397 if (osd_backup->layer[index].enable) {
Googler9398cc32022-12-02 17:21:52 +08005398 osd_log_info("%d\t%4d\t 0x%8lx %2d\t%2d\t%2d\t%2d\t0x%x\t(%4d,%4d,%4d,%4d)\t(%4d,%4d,%4d,%4d)\n",
5399 index,
5400 osd_backup->layer[index].enable,
5401 osd_backup->layer[index].ext_addr,
5402 osd_backup->layer[index].zorder,
5403 osd_backup->layer[index].blend_mode,
5404 osd_backup->layer[index].plane_alpha,
5405 osd_backup->layer[index].dim_layer,
5406 osd_backup->layer[index].dim_color,
5407 osd_backup->layer[index].src_x,
5408 osd_backup->layer[index].src_y,
5409 osd_backup->layer[index].src_w,
5410 osd_backup->layer[index].src_h,
5411 osd_backup->layer[index].dst_x,
5412 osd_backup->layer[index].dst_y,
5413 osd_backup->layer[index].dst_w,
5414 osd_backup->layer[index].dst_h);
Googler4f18c0c2022-09-20 17:23:36 +08005415 }
5416 }
5417
Googler9398cc32022-12-02 17:21:52 +08005418 osd_blend_reg = &osd_backup->osd_blend_reg;
5419 vpp0_blend_reg = &osd_backup->vpp0_blend_reg;
5420
5421 value = 4 << 29 |
5422 osd_blend_reg->blend2_premult_en << 27 |
5423 osd_blend_reg->din0_byp_blend << 26 |
5424 osd_blend_reg->din2_osd_sel << 25 |
5425 osd_blend_reg->din3_osd_sel << 24 |
5426 osd_blend_reg->blend_din_en << 20 |
5427 osd_blend_reg->din_premult_en << 16 |
5428 osd_blend_reg->din_reoder_sel;
Googler4f18c0c2022-09-20 17:23:36 +08005429 osd_log_info("(0x39b0)=0x%x\n", value);
Googler9398cc32022-12-02 17:21:52 +08005430 osd_log_info("(0x39bb)=0x%x\n",
5431 osd_blend_reg->osd_blend_blend0_size);
5432 osd_log_info("(0x39bc)=0x%x\n",
5433 osd_blend_reg->osd_blend_blend0_size);
5434
Googler4f18c0c2022-09-20 17:23:36 +08005435 for (index = 0; index < HW_OSD_COUNT; index++) {
5436 if (osd_hw.enable[index]) {
5437 osd_log_info("(0x%x)=0x%x, (0x%x)=0x%x\n",
Googler9398cc32022-12-02 17:21:52 +08005438 VIU_OSD_BLEND_DIN0_SCOPE_H + 2 * index,
5439 osd_blend_reg->osd_blend_din_scope_h[index],
5440 VIU_OSD_BLEND_DIN0_SCOPE_V + 2 * index,
5441 osd_blend_reg->osd_blend_din_scope_v[index]);
Googler4f18c0c2022-09-20 17:23:36 +08005442 }
5443 }
5444 /* vpp osd1 blend ctrl */
5445 value = (0 & 0xf) << 0 |
5446 (0 & 0x1) << 4 |
Googler9398cc32022-12-02 17:21:52 +08005447 (vpp0_blend_reg->postbld_src3_sel & 0xf) << 8 |
5448 (vpp0_blend_reg->postbld_osd1_premult & 0x1) << 16 |
Googler4f18c0c2022-09-20 17:23:36 +08005449 (1 & 0x1) << 20;
5450 osd_log_info("(0x1dfd)=0x%x\n", value);
Googler4f18c0c2022-09-20 17:23:36 +08005451
5452 /* vpp osd2 blend ctrl */
5453 value = (0 & 0xf) << 0 |
5454 (0 & 0x1) << 4 |
Googler9398cc32022-12-02 17:21:52 +08005455 (vpp0_blend_reg->postbld_src4_sel & 0xf) << 8 |
5456 (vpp0_blend_reg->postbld_osd2_premult & 0x1) << 16 |
Googler4f18c0c2022-09-20 17:23:36 +08005457 (1 & 0x1) << 20;
5458 osd_log_info("(0x1dfe)=0x%x\n", value);
Googler4f18c0c2022-09-20 17:23:36 +08005459 osd_log_info("(0x1df5)=0x%x, (0x1df6)=0x%x\n",
Googler9398cc32022-12-02 17:21:52 +08005460 vpp0_blend_reg->osd1_h_start << 16 |
5461 vpp0_blend_reg->osd1_h_end,
5462 vpp0_blend_reg->osd1_v_start << 16 |
5463 vpp0_blend_reg->osd1_v_end);
Googler4f18c0c2022-09-20 17:23:36 +08005464 osd_log_info("(0x1df7)=0x%x, (0x1df8)=0x%x\n",
Googler9398cc32022-12-02 17:21:52 +08005465 vpp0_blend_reg->osd2_h_start << 16 |
5466 vpp0_blend_reg->osd2_h_end,
5467 vpp0_blend_reg->osd2_v_start << 16 |
5468 vpp0_blend_reg->osd2_v_end);
Googler4f18c0c2022-09-20 17:23:36 +08005469}
5470
5471void output_save_info(void)
5472{
5473 struct osd_debug_backup_s *osd_backup;
5474 int count = osd_hw.osd_debug.backup_count - 1;
5475 int i;
5476
5477 osd_backup = &osd_hw.osd_debug.osd_backup[count];
5478 for (i = count; i >= 0; i--) {
5479 osd_log_info("save list %d\n", i);
5480 osd_info_output(i);
5481 }
5482 for (i = OSD_BACKUP_COUNT - 1; i > count; i--) {
5483 osd_log_info("save list %d\n", i);
5484 osd_info_output(i);
5485 }
5486}
5487
5488#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
5489enum {
5490 HAL_PIXEL_FORMAT_RGBA_8888 = 1,
5491 HAL_PIXEL_FORMAT_RGBX_8888 = 2,
5492 HAL_PIXEL_FORMAT_RGB_888 = 3,
5493 HAL_PIXEL_FORMAT_RGB_565 = 4,
5494 HAL_PIXEL_FORMAT_BGRA_8888 = 5,
5495 HAL_PIXEL_FORMAT_RGBA_1010102 = 43,
5496 /* 0x2B */
5497};
5498
5499static bool use_ext;
5500const struct color_bit_define_s extern_color_format_array[] = {
5501 /*32 bit color RGBA */
5502 {
5503 COLOR_INDEX_32_ABGR, 2, 5,
5504 0, 8, 0, 8, 8, 0, 16, 8, 0, 24, 8, 0,
5505 0, 32
5506 },
5507 /*32 bit color RGBX */
5508 {
5509 COLOR_INDEX_32_XBGR, 2, 5,
5510 0, 8, 0, 8, 8, 0, 16, 8, 0, 24, 0, 0,
5511 0, 32
5512 },
5513 /*24 bit color RGB */
5514 {
5515 COLOR_INDEX_24_RGB, 5, 7,
5516 16, 8, 0, 8, 8, 0, 0, 8, 0, 0, 0, 0,
5517 0, 24
5518 },
5519 /*16 bit color BGR */
5520 {
5521 COLOR_INDEX_16_565, 4, 4,
5522 11, 5, 0, 5, 6, 0, 0, 5, 0, 0, 0, 0,
5523 0, 16
5524 },
5525 /*32 bit color BGRA */
5526 {
5527 COLOR_INDEX_32_ARGB, 1, 5,
5528 16, 8, 0, 8, 8, 0, 0, 8, 0, 24, 8, 0,
5529 0, 32
5530 },
5531 /*32 bit color RGBA 1010102 for mali afbc*/
5532 {
5533 COLOR_INDEX_RGBA_1010102, 2, 9,
5534 0, 10, 0, 10, 10, 0, 20, 10, 0, 30, 2, 0,
5535 0, 32
5536 },
5537};
5538
5539static void clear_backup_info(void)
5540{
5541 struct osd_debug_backup_s *osd_backup;
5542 int count = osd_hw.osd_debug.backup_count;
5543 int i;
5544
5545 osd_backup = &osd_hw.osd_debug.osd_backup[count];
5546 for (i = 0; i < HW_OSD_COUNT; i++)
Googler9398cc32022-12-02 17:21:52 +08005547 memset(&osd_backup->layer[i], 0x0,
5548 sizeof(struct layer_info_s));
Googler4f18c0c2022-09-20 17:23:36 +08005549}
5550
5551static void save_layer_info(struct layer_fence_map_s *layer_map)
5552{
5553 struct osd_debug_backup_s *osd_backup;
5554 int count = osd_hw.osd_debug.backup_count;
5555 u32 index = layer_map->fb_index;
5556
Googler9398cc32022-12-02 17:21:52 +08005557 if (index >= OSD_MAX)
5558 return;
Googler4f18c0c2022-09-20 17:23:36 +08005559 osd_backup = &osd_hw.osd_debug.osd_backup[count];
5560 osd_backup->layer[index].enable = layer_map->enable;
5561 osd_backup->layer[index].ext_addr = layer_map->ext_addr;
5562 osd_backup->layer[index].src_x = layer_map->src_x;
5563 osd_backup->layer[index].src_y = layer_map->src_y;
5564 osd_backup->layer[index].src_w = layer_map->src_w;
5565 osd_backup->layer[index].src_h = layer_map->src_h;
5566 osd_backup->layer[index].dst_x = layer_map->dst_x;
5567 osd_backup->layer[index].dst_y = layer_map->dst_y;
5568 osd_backup->layer[index].dst_w = layer_map->dst_w;
5569 osd_backup->layer[index].dst_h = layer_map->dst_h;
5570 osd_backup->layer[index].zorder = layer_map->zorder;
5571 osd_backup->layer[index].blend_mode = layer_map->blend_mode;
5572 osd_backup->layer[index].plane_alpha = layer_map->plane_alpha;
5573 osd_backup->layer[index].dim_layer = layer_map->dim_layer;
5574 osd_backup->layer[index].dim_color = layer_map->dim_color;
5575}
5576
5577static const struct color_bit_define_s *convert_hal_format(u32 format)
5578{
5579 const struct color_bit_define_s *color = NULL;
5580 int b_mali_afbc = 0;
5581
5582 b_mali_afbc = (format & AFBC_EN) >> 31;
5583 format &= ~AFBC_EN;
5584 switch (format) {
5585 case HAL_PIXEL_FORMAT_RGBA_8888:
5586 case HAL_PIXEL_FORMAT_RGBX_8888:
5587 case HAL_PIXEL_FORMAT_RGB_888:
5588 case HAL_PIXEL_FORMAT_RGB_565:
5589 case HAL_PIXEL_FORMAT_BGRA_8888:
5590 color = &extern_color_format_array[format - 1];
5591 break;
5592 case HAL_PIXEL_FORMAT_RGBA_1010102:
5593 if (b_mali_afbc)
5594 color = &extern_color_format_array[format - 38];
5595 break;
5596 }
5597 return color;
5598}
5599
5600static bool osd_ge2d_compose_pan_display(struct osd_fence_map_s *fence_map)
5601{
5602 u32 index = fence_map->fb_index;
5603 bool free_scale_set = false;
5604
Googler9398cc32022-12-02 17:21:52 +08005605#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler4f18c0c2022-09-20 17:23:36 +08005606 canvas_config(osd_hw.fb_gem[index].canvas_idx,
Googler9398cc32022-12-02 17:21:52 +08005607 fence_map->ext_addr,
5608 CANVAS_ALIGNED(fence_map->width *
5609 (osd_hw.color_info[index]->bpp >> 3)),
5610 fence_map->height,
5611 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
5612#endif
Googler4f18c0c2022-09-20 17:23:36 +08005613 osd_hw.screen_base[index] = fence_map->ext_addr;
5614 osd_hw.screen_size[index] =
5615 CANVAS_ALIGNED(fence_map->width *
5616 osd_hw.color_info[index]->bpp) * fence_map->height;
5617 osd_hw.pandata[index].x_start = 0;
5618 osd_hw.pandata[index].x_end = fence_map->width - 1;
5619 osd_hw.pandata[index].y_start = 0;
5620 osd_hw.pandata[index].y_end = fence_map->height - 1;
Googler4f18c0c2022-09-20 17:23:36 +08005621 if ((memcmp(&osd_hw.dispdata[index],
Googler9398cc32022-12-02 17:21:52 +08005622 &osd_hw.dispdata_backup[index],
5623 sizeof(struct pandata_s)) != 0) ||
5624 (memcmp(&osd_hw.free_src_data[index],
5625 &osd_hw.free_src_data_backup[index],
5626 sizeof(struct pandata_s)) != 0) ||
5627 (memcmp(&osd_hw.free_dst_data[index],
5628 &osd_hw.free_dst_data_backup[index],
5629 sizeof(struct pandata_s)) != 0)) {
Googler4f18c0c2022-09-20 17:23:36 +08005630 memcpy(&osd_hw.dispdata[index],
Googler9398cc32022-12-02 17:21:52 +08005631 &osd_hw.dispdata_backup[index],
5632 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08005633 memcpy(&osd_hw.free_src_data[index],
Googler9398cc32022-12-02 17:21:52 +08005634 &osd_hw.free_src_data_backup[index],
5635 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08005636 memcpy(&osd_hw.free_dst_data[index],
Googler9398cc32022-12-02 17:21:52 +08005637 &osd_hw.free_dst_data_backup[index],
5638 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08005639 free_scale_set = true;
5640 }
5641
Googler9398cc32022-12-02 17:21:52 +08005642 if (osd_hw.free_scale[index].h_enable !=
5643 osd_hw.free_scale_backup[index].h_enable ||
5644 osd_hw.free_scale[index].v_enable !=
5645 osd_hw.free_scale_backup[index].v_enable ||
5646 osd_hw.free_scale_enable[index] !=
5647 osd_hw.free_scale_enable_backup[index] ||
5648 osd_hw.free_scale_mode[index] !=
5649 osd_hw.free_scale_mode_backup[index]) {
Googler4f18c0c2022-09-20 17:23:36 +08005650 osd_hw.free_scale[index].h_enable =
5651 osd_hw.free_scale_backup[index].h_enable;
5652 osd_hw.free_scale[index].v_enable =
5653 osd_hw.free_scale_backup[index].v_enable;
5654 osd_hw.free_scale_enable[index] =
5655 osd_hw.free_scale_enable_backup[index];
5656 osd_hw.free_scale_mode[index] =
5657 osd_hw.free_scale_mode_backup[index];
5658 free_scale_set = true;
5659 }
5660 return free_scale_set;
5661}
5662
5663static bool osd_direct_compose_pan_display(struct osd_fence_map_s *fence_map)
5664{
5665 u32 index = fence_map->fb_index;
5666 u32 ext_addr = fence_map->ext_addr;
5667 u32 width_src = 0, width_dst = 0, height_src = 0, height_dst = 0;
5668 u32 x_start, x_end, y_start, y_end;
5669 bool freescale_update = false;
5670 struct pandata_s freescale_dst[HW_OSD_COUNT];
5671
5672 ext_addr = ext_addr + fence_map->byte_stride * fence_map->yoffset;
5673
5674 if (!osd_hw.osd_afbcd[index].enable) {
Googler9398cc32022-12-02 17:21:52 +08005675 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler4f18c0c2022-09-20 17:23:36 +08005676 canvas_config(osd_hw.fb_gem[index].canvas_idx,
Googler9398cc32022-12-02 17:21:52 +08005677 ext_addr,
5678 CANVAS_ALIGNED(fence_map->byte_stride),
5679 fence_map->height,
5680 CANVAS_ADDR_NOWRAP,
5681 CANVAS_BLKMODE_LINEAR);
5682 #endif
Googler4f18c0c2022-09-20 17:23:36 +08005683 osd_hw.screen_base[index] = ext_addr;
5684 osd_hw.screen_size[index] =
5685 fence_map->byte_stride * fence_map->height;
5686 } else {
5687 osd_hw.osd_afbcd[index].phy_addr = ext_addr;
5688 osd_hw.osd_afbcd[index].frame_width =
5689 fence_map->width;
5690 osd_hw.osd_afbcd[index].frame_height =
5691 fence_map->height;
5692 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
5693 if (fence_map->width <= 128)
5694 osd_hw.osd_afbcd[index].conv_lbuf_len = 32;
5695 else if (fence_map->width <= 256)
5696 osd_hw.osd_afbcd[index].conv_lbuf_len = 64;
5697 else if (fence_map->width <= 512)
5698 osd_hw.osd_afbcd[index].conv_lbuf_len = 128;
5699 else if (fence_map->width <= 1024)
5700 osd_hw.osd_afbcd[index].conv_lbuf_len = 256;
5701 else if (fence_map->width <= 2048)
5702 osd_hw.osd_afbcd[index].conv_lbuf_len = 512;
5703 else
5704 osd_hw.osd_afbcd[index].conv_lbuf_len = 1024;
5705 }
5706 osd_hw.screen_base[index] = ext_addr;
5707 osd_hw.screen_size[index] = fence_map->afbc_len;
5708 }
5709 width_dst = osd_hw.free_dst_data_backup[index].x_end -
5710 osd_hw.free_dst_data_backup[index].x_start + 1;
5711 width_src = osd_hw.free_src_data_backup[index].x_end -
5712 osd_hw.free_src_data_backup[index].x_start + 1;
5713
5714 height_dst = osd_hw.free_dst_data_backup[index].y_end -
5715 osd_hw.free_dst_data_backup[index].y_start + 1;
5716 height_src = osd_hw.free_src_data_backup[index].y_end -
5717 osd_hw.free_src_data_backup[index].y_start + 1;
5718 if (osd_hw.free_scale_enable[index] ||
Googler9398cc32022-12-02 17:21:52 +08005719 width_src != width_dst ||
5720 height_src != height_dst ||
5721 fence_map->width != fence_map->dst_w ||
5722 fence_map->height != fence_map->dst_h) {
Googler4f18c0c2022-09-20 17:23:36 +08005723 osd_hw.free_scale[index].h_enable = 1;
5724 osd_hw.free_scale[index].v_enable = 1;
5725 osd_hw.free_scale_enable[index] = 0x10001;
5726 osd_hw.free_scale_mode[index] = 1;
5727 if (osd_hw.free_scale_enable[index] !=
5728 osd_hw.free_scale_enable_backup[index]) {
5729 /* Todo: */
5730 osd_set_scan_mode(index);
5731 freescale_update = true;
5732 }
5733
5734 osd_hw.pandata[index].x_start = fence_map->xoffset;
5735 osd_hw.pandata[index].x_end =
5736 fence_map->xoffset + fence_map->width - 1;
5737 osd_hw.pandata[index].y_start = 0;
5738 osd_hw.pandata[index].y_end = fence_map->height - 1;
5739
Googler4f18c0c2022-09-20 17:23:36 +08005740 freescale_dst[index].x_start =
5741 osd_hw.free_dst_data_backup[index].x_start +
5742 (fence_map->dst_x * width_dst) / width_src;
5743 freescale_dst[index].x_end =
5744 osd_hw.free_dst_data_backup[index].x_start +
5745 ((fence_map->dst_x + fence_map->dst_w) *
5746 width_dst) / width_src - 1;
5747
5748 freescale_dst[index].y_start =
5749 osd_hw.free_dst_data_backup[index].y_start +
5750 (fence_map->dst_y * height_dst) / height_src;
5751 freescale_dst[index].y_end =
5752 osd_hw.free_dst_data_backup[index].y_start +
5753 ((fence_map->dst_y + fence_map->dst_h) *
5754 height_dst) / height_src - 1;
5755
5756 if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
5757 x_start = osd_hw.vinfo_width[VIU1]
5758 - freescale_dst[index].x_end - 1;
5759 y_start = osd_hw.vinfo_height[VIU1]
5760 - freescale_dst[index].y_end - 1;
5761 x_end = osd_hw.vinfo_width[VIU1]
5762 - freescale_dst[index].x_start - 1;
5763 y_end = osd_hw.vinfo_height[VIU1]
5764 - freescale_dst[index].y_start - 1;
5765 freescale_dst[index].x_start = x_start;
5766 freescale_dst[index].y_start = y_start;
5767 freescale_dst[index].x_end = x_end;
5768 freescale_dst[index].y_end = y_end;
5769 } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
5770 x_start = osd_hw.vinfo_width[VIU1]
5771 - freescale_dst[index].x_end - 1;
5772 x_end = osd_hw.vinfo_width[VIU1]
5773 - freescale_dst[index].x_start - 1;
5774 freescale_dst[index].x_start = x_start;
5775 freescale_dst[index].x_end = x_end;
5776
5777 } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
5778 y_start = osd_hw.vinfo_height[VIU1]
5779 - freescale_dst[index].y_end - 1;
5780 y_end = osd_hw.vinfo_height[VIU1]
5781 - freescale_dst[index].y_start - 1;
5782 freescale_dst[index].y_start = y_start;
5783 freescale_dst[index].y_end = y_end;
5784 }
Googler9398cc32022-12-02 17:21:52 +08005785 if (memcmp(&osd_hw.free_src_data[index],
5786 &osd_hw.pandata[index],
5787 sizeof(struct pandata_s)) != 0 ||
5788 memcmp(&osd_hw.free_dst_data[index],
5789 &freescale_dst[index],
5790 sizeof(struct pandata_s)) != 0) {
5791 memcpy(&osd_hw.free_src_data[index],
5792 &osd_hw.pandata[index],
5793 sizeof(struct pandata_s));
5794 memcpy(&osd_hw.free_dst_data[index],
5795 &freescale_dst[index],
5796 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08005797 freescale_update = true;
Googler9398cc32022-12-02 17:21:52 +08005798
Googler9726be62022-12-14 05:53:31 +00005799 if ((height_dst != height_src ||
5800 width_dst != width_src) &&
5801 osd_hw.free_dst_data[index].y_end <
5802 osd_hw.vinfo_height[VIU1] - 1)
Googler4f18c0c2022-09-20 17:23:36 +08005803 osd_set_dummy_data(index, 0);
5804 else
5805 osd_set_dummy_data(index, 0xff);
5806 osd_log_dbg(MODULE_BASE,
Googler9398cc32022-12-02 17:21:52 +08005807 "direct pandata x=%d,x_end=%d,y=%d,y_end=%d,width=%d,height=%d\n",
5808 osd_hw.pandata[index].x_start,
5809 osd_hw.pandata[index].x_end,
5810 osd_hw.pandata[index].y_start,
5811 osd_hw.pandata[index].y_end,
5812 fence_map->width,
5813 fence_map->height);
Googler4f18c0c2022-09-20 17:23:36 +08005814 osd_log_dbg(MODULE_BASE,
Googler9398cc32022-12-02 17:21:52 +08005815 "fence_map:xoffset=%d,yoffset=%d\n",
5816 fence_map->xoffset,
5817 fence_map->yoffset);
Googler4f18c0c2022-09-20 17:23:36 +08005818 osd_log_dbg(MODULE_BASE,
Googler9398cc32022-12-02 17:21:52 +08005819 "fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d,byte_stride=%d\n",
5820 fence_map->dst_x,
5821 fence_map->dst_y,
5822 fence_map->dst_w,
5823 fence_map->dst_h,
5824 fence_map->byte_stride);
Googler4f18c0c2022-09-20 17:23:36 +08005825 }
5826 } else {
5827 osd_hw.pandata[index].x_start = 0;
5828 osd_hw.pandata[index].x_end = fence_map->width - 1;
5829 osd_hw.pandata[index].y_start = 0;
5830 osd_hw.pandata[index].y_end = fence_map->height - 1;
5831
5832 osd_hw.dispdata[index].x_start = fence_map->dst_x;
5833 osd_hw.dispdata[index].x_end =
5834 fence_map->dst_x + fence_map->dst_w - 1;
5835 osd_hw.dispdata[index].y_start = fence_map->dst_y;
5836 osd_hw.dispdata[index].y_end =
5837 fence_map->dst_y + fence_map->dst_h - 1;
5838 if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
5839 x_start = osd_hw.vinfo_width[VIU1]
5840 - osd_hw.dispdata[index].x_end - 1;
5841 y_start = osd_hw.vinfo_height[VIU1]
5842 - osd_hw.dispdata[index].y_end - 1;
5843 x_end = osd_hw.vinfo_width[VIU1]
5844 - osd_hw.dispdata[index].x_start - 1;
5845 y_end = osd_hw.vinfo_height[VIU1]
5846 - osd_hw.dispdata[index].y_start - 1;
5847 osd_hw.dispdata[index].x_start = x_start;
5848 osd_hw.dispdata[index].y_start = y_start;
5849 osd_hw.dispdata[index].x_end = x_end;
5850 osd_hw.dispdata[index].y_end = y_end;
5851 } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
5852 x_start = osd_hw.vinfo_width[VIU1]
5853 - osd_hw.dispdata[index].x_end - 1;
5854 x_end = osd_hw.vinfo_width[VIU1]
5855 - osd_hw.dispdata[index].x_start - 1;
5856 osd_hw.dispdata[index].x_start = x_start;
5857 osd_hw.dispdata[index].x_end = x_end;
Googler4f18c0c2022-09-20 17:23:36 +08005858 } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
5859 y_start = osd_hw.vinfo_height[VIU1]
5860 - osd_hw.dispdata[index].y_end - 1;
5861 y_end = osd_hw.vinfo_height[VIU1]
5862 - osd_hw.dispdata[index].y_start - 1;
5863 osd_hw.dispdata[index].y_start = y_start;
5864 osd_hw.dispdata[index].y_end = y_end;
5865 }
5866 }
5867 fence_map->ext_addr = ext_addr;
5868 return freescale_update;
5869}
5870
5871static void osd_pan_display_single_fence(struct osd_fence_map_s *fence_map)
5872{
5873 s32 ret = 1;
5874 long diff_x, diff_y;
5875 u32 index = fence_map->fb_index;
5876 u32 xoffset = fence_map->xoffset;
5877 u32 yoffset = fence_map->yoffset;
5878 const struct color_bit_define_s *color = NULL;
5879 bool color_mode = false;
5880 bool freescale_update = false;
5881 u32 osd_enable = 0;
5882 bool skip = false;
Googler9398cc32022-12-02 17:21:52 +08005883 const struct vinfo_s *vinfo = NULL;
Googler4f18c0c2022-09-20 17:23:36 +08005884 u32 output_index = VIU1;
5885
5886 if (index >= OSD2)
5887 goto out;
Googler9398cc32022-12-02 17:21:52 +08005888#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +08005889 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08005890#endif
5891 if (!vinfo || !vinfo->name || (!strcmp(vinfo->name, "invalid") ||
5892 !strcmp(vinfo->name, "null")))
Googler4f18c0c2022-09-20 17:23:36 +08005893 goto out;
5894
5895 osd_hw.vinfo_width[output_index] = vinfo->width;
5896 osd_hw.vinfo_height[output_index] = vinfo->height;
5897
5898 if (timeline_created[output_index]) { /* out fence created success. */
5899 ret = osd_wait_buf_ready(fence_map);
5900 if (ret < 0)
5901 osd_log_dbg(MODULE_BASE, "fence wait ret %d\n", ret);
5902 }
5903 if (ret) {
5904 osd_hw.buffer_alloc[index] = 1;
5905 if (osd_hw.osd_fps_start[output_index])
5906 osd_hw.osd_fps[output_index]++;
5907 if (fence_map->op == 0xffffffff)
5908 skip = true;
5909 else
5910 osd_enable = (fence_map->op & 1) ? DISABLE : ENABLE;
5911 /* need update via direct render interface later */
5912 //fence_map->afbc_en = osd_hw.osd_afbcd[index].enable;
Googler9398cc32022-12-02 17:21:52 +08005913 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE &&
5914 osd_hw.osd_afbcd[index].enable) {
Googler4f18c0c2022-09-20 17:23:36 +08005915 osd_hw.osd_afbcd[index].inter_format =
5916 AFBC_EN | BLOCK_SPLIT |
5917 YUV_TRANSFORM | SUPER_BLOCK_ASPECT;
5918 }
5919 /* Todo: */
Googler9398cc32022-12-02 17:21:52 +08005920 if (fence_map->ext_addr && fence_map->width &&
5921 fence_map->height) {
Googler4f18c0c2022-09-20 17:23:36 +08005922 spin_lock_irqsave(&osd_lock, lock_flags);
5923 use_ext = true;
5924 if (!osd_hw.osd_afbcd[index].enable) {
5925 osd_hw.fb_gem[index].canvas_idx =
5926 osd_extra_idx[index][ext_canvas_id[index]];
5927 ext_canvas_id[index] ^= 1;
5928 osd_hw.osd_afbcd[index].enable = DISABLE;
Googler9398cc32022-12-02 17:21:52 +08005929 } else {
Googler4f18c0c2022-09-20 17:23:36 +08005930 osd_hw.osd_afbcd[index].enable = ENABLE;
Googler9398cc32022-12-02 17:21:52 +08005931 }
Googler4f18c0c2022-09-20 17:23:36 +08005932 color = convert_hal_format(fence_map->format);
Googler9398cc32022-12-02 17:21:52 +08005933 if (color)
Googler4f18c0c2022-09-20 17:23:36 +08005934 osd_hw.color_info[index] = color;
Googler9398cc32022-12-02 17:21:52 +08005935 else
Googler4f18c0c2022-09-20 17:23:36 +08005936 osd_log_err("fence color format error %d\n",
Googler9398cc32022-12-02 17:21:52 +08005937 fence_map->format);
Googler4f18c0c2022-09-20 17:23:36 +08005938
5939 if (DIRECT_COMPOSE_MODE ==
5940 fence_map->compose_type)
5941 freescale_update =
5942 osd_direct_compose_pan_display(fence_map);
5943 else if (GE2D_COMPOSE_MODE ==
5944 fence_map->compose_type) {
5945 freescale_update =
5946 osd_ge2d_compose_pan_display(fence_map);
5947 if (freescale_update)
5948 osd_set_dummy_data(index, 0xff);
5949 }
5950
5951 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
5952
5953 /* geometry and freescale need update with ioctl */
5954 osd_hw.reg[DISP_GEOMETRY].update_func(index);
5955 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
Googler9398cc32022-12-02 17:21:52 +08005956 if ((osd_hw.free_scale_enable[index] &&
5957 osd_update_window_axis) ||
5958 freescale_update) {
Googler9726be62022-12-14 05:53:31 +00005959 if (!osd_hw.osd_display_debug[output_index])
Googler9398cc32022-12-02 17:21:52 +08005960 osd_hw.reg[DISP_FREESCALE_ENABLE]
5961 .update_func(index);
Googler4f18c0c2022-09-20 17:23:36 +08005962 osd_update_window_axis = false;
5963 }
5964 if ((osd_enable != osd_hw.enable[index] ||
Googler9398cc32022-12-02 17:21:52 +08005965 (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
5966 osd_hw.osd_afbcd[index].enable)) &&
5967 !skip && !suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +08005968 osd_hw.enable[index] = osd_enable;
Googler9726be62022-12-14 05:53:31 +00005969 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +08005970 osd_hw.reg[OSD_ENABLE]
5971 .update_func(index);
5972 }
5973 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +08005974 osd_mali_afbc_start(output_index);
Googler4f18c0c2022-09-20 17:23:36 +08005975 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +00005976 osd_wait_vsync_hw(index);
Googler9398cc32022-12-02 17:21:52 +08005977 } else if (xoffset != osd_hw.pandata[index].x_start ||
5978 yoffset != osd_hw.pandata[index].y_start ||
5979 use_ext) {
Googler4f18c0c2022-09-20 17:23:36 +08005980 spin_lock_irqsave(&osd_lock, lock_flags);
5981 if (use_ext) {
5982 osd_hw.fb_gem[index].canvas_idx =
5983 OSD1_CANVAS_INDEX;
5984
5985 osd_hw.pandata[index].x_start = xoffset;
5986 osd_hw.pandata[index].x_end = xoffset +
5987 osd_hw.fb_gem[index].xres - 1;
5988 osd_hw.pandata[index].y_start = yoffset;
5989 osd_hw.pandata[index].y_end = yoffset +
5990 osd_hw.fb_gem[index].yres - 1;
5991 osd_hw.screen_base[index] =
5992 osd_hw.screen_base_backup[index];
5993 osd_hw.screen_size[index] =
5994 osd_hw.screen_size_backup[index];
5995
5996 osd_hw.dispdata[index].x_start =
5997 osd_hw.dispdata_backup[index].x_start;
5998 osd_hw.dispdata[index].x_end =
5999 osd_hw.dispdata_backup[index].x_end;
6000 osd_hw.dispdata[index].y_start =
6001 osd_hw.dispdata_backup[index].y_start;
6002 osd_hw.dispdata[index].y_end =
6003 osd_hw.dispdata_backup[index].y_end;
6004
6005 /* restore free_scale info */
6006 osd_hw.free_scale[index].h_enable =
6007 osd_hw.free_scale_backup[index].h_enable;
6008 osd_hw.free_scale[index].v_enable =
6009 osd_hw.free_scale_backup[index].v_enable;
6010 osd_hw.free_scale_enable[index] =
6011 osd_hw.free_scale_enable_backup[index];
6012 osd_hw.free_scale_mode[index] =
6013 osd_hw.free_scale_mode_backup[index];
6014
6015 memcpy(&osd_hw.free_src_data[index],
Googler9398cc32022-12-02 17:21:52 +08006016 &osd_hw.free_src_data_backup[index],
6017 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08006018 memcpy(&osd_hw.free_dst_data[index],
Googler9398cc32022-12-02 17:21:52 +08006019 &osd_hw.free_dst_data_backup[index],
6020 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08006021 osd_set_dummy_data(index, 0xff);
6022 osd_log_dbg(MODULE_BASE,
Googler9398cc32022-12-02 17:21:52 +08006023 "switch back dispdata_backup x=%d,x_end=%d,y=%d,y_end=%d\n",
6024 osd_hw.dispdata_backup[index].x_start,
6025 osd_hw.dispdata_backup[index].x_end,
6026 osd_hw.dispdata_backup[index].y_start,
6027 osd_hw.dispdata_backup[index].y_end);
6028 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler4f18c0c2022-09-20 17:23:36 +08006029 canvas_config(osd_hw.fb_gem[index].canvas_idx,
Googler9398cc32022-12-02 17:21:52 +08006030 osd_hw.fb_gem[index].addr,
6031 CANVAS_ALIGNED
6032 (osd_hw.fb_gem[index].width),
6033 osd_hw.fb_gem[index].height,
6034 CANVAS_ADDR_NOWRAP,
6035 CANVAS_BLKMODE_LINEAR);
6036 #endif
Googler4f18c0c2022-09-20 17:23:36 +08006037 use_ext = false;
6038 color_mode = true;
6039 freescale_update = true;
6040 } else {
6041 diff_x = xoffset -
6042 osd_hw.pandata[index].x_start;
6043 diff_y = yoffset -
6044 osd_hw.pandata[index].y_start;
6045 osd_hw.pandata[index].x_start += diff_x;
6046 osd_hw.pandata[index].x_end += diff_x;
6047 osd_hw.pandata[index].y_start += diff_y;
6048 osd_hw.pandata[index].y_end += diff_y;
6049 }
6050 if (osd_hw.osd_afbcd[index].enable == ENABLE) {
6051 /* osd_hw.osd_afbcd[index].phy_addr =
6052 * (osd_hw.pandata[index].y_start /
6053 * osd_hw.osd_afbcd[index].frame_height) *
6054 * osd_hw.osd_afbcd[index].frame_height *
6055 * osd_hw.fb_gem[index].width;
6056 * osd_hw.osd_afbcd[index].phy_addr +=
6057 * osd_hw.fb_gem[index].addr;
6058 */
6059 osd_hw.osd_afbcd[index].phy_addr =
6060 osd_hw.osd_afbcd[index].addr
6061 [osd_hw.pandata[index].y_start /
6062 osd_hw.osd_afbcd[index].frame_height];
6063 }
6064 color = convert_hal_format(fence_map->format);
6065 if (color) {
6066 if (color != osd_hw.color_backup[index]) {
6067 color_mode = true;
6068 osd_hw.color_backup[index] = color;
6069 }
6070 osd_hw.color_info[index] = color;
6071 } else {
6072 osd_log_err("fence color format error %d\n",
Googler9398cc32022-12-02 17:21:52 +08006073 fence_map->format);
Googler4f18c0c2022-09-20 17:23:36 +08006074 }
6075 if (color_mode)
6076 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
6077 osd_hw.reg[DISP_GEOMETRY].update_func(index);
6078 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
Googler9398cc32022-12-02 17:21:52 +08006079 if ((osd_hw.free_scale_enable[index] &&
6080 osd_update_window_axis) ||
6081 (osd_hw.free_scale_enable[index] &&
6082 freescale_update)) {
Googler9726be62022-12-14 05:53:31 +00006083 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +08006084 osd_hw.reg[DISP_FREESCALE_ENABLE]
6085 .update_func(index);
6086 osd_update_window_axis = false;
6087 }
6088 if ((osd_enable != osd_hw.enable[index] ||
Googler9398cc32022-12-02 17:21:52 +08006089 (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
6090 osd_hw.osd_afbcd[index].enable)) &&
6091 !skip && !suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +08006092 osd_hw.enable[index] = osd_enable;
Googler9726be62022-12-14 05:53:31 +00006093 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +08006094 osd_hw.reg[OSD_ENABLE]
6095 .update_func(index);
6096 }
6097 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +08006098 osd_mali_afbc_start(output_index);
Googler4f18c0c2022-09-20 17:23:36 +08006099 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +00006100 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08006101 } else if ((osd_enable != osd_hw.enable[index] ||
6102 (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
Googler9398cc32022-12-02 17:21:52 +08006103 osd_hw.osd_afbcd[index].enable)) && !skip) {
Googler4f18c0c2022-09-20 17:23:36 +08006104 spin_lock_irqsave(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +08006105 if (!suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +08006106 osd_hw.enable[index] = osd_enable;
Googler9726be62022-12-14 05:53:31 +00006107 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +08006108 osd_hw.reg[OSD_ENABLE]
6109 .update_func(index);
6110 }
6111 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +08006112 osd_mali_afbc_start(output_index);
Googler4f18c0c2022-09-20 17:23:36 +08006113 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +00006114 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +08006115 }
6116 }
6117#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
6118 if (ret)
6119 osd_ext_clone_pan(index);
6120#endif
6121out:
6122 if (timeline_created[output_index]) {
6123 if (ret)
6124 osd_timeline_increase(output_index);
6125 else
6126 osd_log_err("------NOT signal out_fence ERROR\n");
6127 }
6128 if (fence_map->in_fence)
6129 osd_put_fenceobj(fence_map->in_fence);
6130}
6131
Googler9398cc32022-12-02 17:21:52 +08006132static void osd_pan_display_single_fence_viu2
6133 (struct osd_fence_map_s *fence_map)
Googler4f18c0c2022-09-20 17:23:36 +08006134{
6135 osd_log_err("osd hwc version not support viu2\n");
6136}
6137
6138static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
6139{
6140 u32 index = layer_map->fb_index;
6141 const struct color_bit_define_s *color = NULL;
Googler9398cc32022-12-02 17:21:52 +08006142 ulong ext_addr = 0;
Googler4f18c0c2022-09-20 17:23:36 +08006143 u32 format = 0;
6144 u32 output_index = 0;
6145
Googler9398cc32022-12-02 17:21:52 +08006146 if (index >= OSD_MAX)
Googler4f18c0c2022-09-20 17:23:36 +08006147 return;
6148 /* get in fence_fd */
6149 osd_hw.in_fd[index] = layer_map->in_fd;
6150 osd_hw.buffer_alloc[index] = 1;
6151 osd_hw.enable[index] = layer_map->enable;
6152 if (osd_hw.enable[index] == 0) {
6153 osd_log_dbg(MODULE_BASE, "osd%d: blanked\n", index);
6154 return;
6155 }
6156 osd_hw.osd_afbcd[index].enable =
6157 (layer_map->afbc_inter_format & AFBC_EN) >> 31;
6158 if (layer_map->plane_alpha == 0xff)
6159 layer_map->plane_alpha = 0x100;
6160 osd_hw.gbl_alpha[index] = layer_map->plane_alpha;
6161 osd_hw.dim_layer[index] = layer_map->dim_layer;
Googler9726be62022-12-14 05:53:31 +00006162 osd_hw.secure_enable[index] = layer_map->secure_enable;
Googler9398cc32022-12-02 17:21:52 +08006163 osd_hw.blend_mode[index] = layer_map->blend_mode;
Googler4f18c0c2022-09-20 17:23:36 +08006164
6165 /* Todo: */
6166 if (layer_map->dim_layer) {
6167 /* osd dim layer */
6168 osd_hw.dim_layer[index] = layer_map->dim_layer;
6169 osd_hw.dim_color[index] = layer_map->dim_color;
6170 osd_hw.order[index] = layer_map->zorder;
6171 switch (layer_map->blend_mode) {
6172 case BLEND_MODE_PREMULTIPLIED:
6173 osd_hw.premult_en[index] = 1;
6174 break;
6175 case BLEND_MODE_COVERAGE:
6176 case BLEND_MODE_NONE:
6177 case BLEND_MODE_INVALID:
6178 osd_hw.premult_en[index] = 0;
6179 break;
6180 }
6181 osd_hw.src_data[index].x = 0;
6182 osd_hw.src_data[index].y = 0;
6183 osd_hw.src_data[index].w = 64;
6184 osd_hw.src_data[index].h = 64;
6185 osd_hw.dst_data[index].x = layer_map->dst_x;
6186 osd_hw.dst_data[index].y = layer_map->dst_y;
6187 osd_hw.dst_data[index].w = layer_map->dst_w;
6188 osd_hw.dst_data[index].h = layer_map->dst_h;
Googler9398cc32022-12-02 17:21:52 +08006189 } else if (layer_map->ext_addr &&
6190 layer_map->src_w &&
6191 layer_map->src_h) {
Googler4f18c0c2022-09-20 17:23:36 +08006192 if (!osd_hw.osd_afbcd[index].enable) {
6193 osd_hw.fb_gem[index].canvas_idx =
6194 osd_extra_idx[index][ext_canvas_id[index]];
6195 ext_canvas_id[index] ^= 1;
6196 osd_hw.osd_afbcd[index].enable = DISABLE;
Googler9398cc32022-12-02 17:21:52 +08006197 } else {
Googler4f18c0c2022-09-20 17:23:36 +08006198 osd_hw.osd_afbcd[index].enable = ENABLE;
Googler9398cc32022-12-02 17:21:52 +08006199 }
Googler4f18c0c2022-09-20 17:23:36 +08006200 if (osd_hw.osd_afbcd[index].enable)
6201 format = layer_map->format | AFBC_EN;
6202 else
6203 format = layer_map->format;
6204 color = convert_hal_format(format);
6205 if (color) {
6206 osd_hw.color_info[index] = color;
6207 } else {
6208 osd_log_err("fence color format error %d\n",
Googler9398cc32022-12-02 17:21:52 +08006209 layer_map->format);
Googler4f18c0c2022-09-20 17:23:36 +08006210 return;
6211 }
6212 if (DIRECT_COMPOSE_MODE !=
6213 layer_map->compose_type)
6214 return;
6215 ext_addr = layer_map->ext_addr;
Googler4f18c0c2022-09-20 17:23:36 +08006216 if (!osd_hw.osd_afbcd[index].enable) {
6217 /*ext_addr is no crop, so height =
6218 * layer_map->src_h + layer_map->src_y
6219 */
6220 osd_hw.fb_gem[index].addr = ext_addr;
6221 osd_hw.fb_gem[index].width = layer_map->byte_stride;
6222 osd_hw.fb_gem[index].height =
6223 layer_map->src_h + layer_map->src_y;
6224 osd_hw.screen_base[index] = ext_addr;
6225 osd_hw.screen_size[index] =
6226 layer_map->byte_stride * layer_map->src_h;
6227 } else {
Googler9398cc32022-12-02 17:21:52 +08006228 if (!osd_hw.afbc_support[index])
6229 pr_err("osd%d: not support afbc\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08006230 osd_hw.osd_afbcd[index].phy_addr = ext_addr;
6231 if (osd_hw.osd_meson_dev.afbc_type ==
6232 MESON_AFBC) {
6233 osd_hw.osd_afbcd[index].frame_width =
6234 layer_map->src_w;
6235 osd_hw.osd_afbcd[index].frame_height =
6236 layer_map->src_h;
6237 if (layer_map->src_w <= 128)
6238 osd_hw.osd_afbcd[index]
6239 .conv_lbuf_len = 32;
6240 else if (layer_map->src_w <= 256)
6241 osd_hw.osd_afbcd[index]
6242 .conv_lbuf_len = 64;
6243 else if (layer_map->src_w <= 512)
6244 osd_hw.osd_afbcd[index]
6245 .conv_lbuf_len = 128;
6246 else if (layer_map->src_w <= 1024)
6247 osd_hw.osd_afbcd[index]
6248 .conv_lbuf_len = 256;
6249 else if (layer_map->src_w <= 2048)
6250 osd_hw.osd_afbcd[index]
6251 .conv_lbuf_len = 512;
6252 else
6253 osd_hw.osd_afbcd[index]
6254 .conv_lbuf_len = 1024;
6255 osd_hw.screen_base[index] = ext_addr;
6256 osd_hw.screen_size[index] =
6257 layer_map->afbc_len;
6258 } else if (osd_hw.osd_meson_dev
6259 .afbc_type == MALI_AFBC) {
6260 osd_hw.osd_afbcd[index].frame_width =
6261 layer_map->byte_stride / 4;
6262 //BYTE_32_ALIGNED(layer_map->src_w);
6263 osd_hw.osd_afbcd[index].frame_height =
6264 BYTE_8_ALIGNED(layer_map->fb_height);
6265 /*BYTE_8_ALIGNED(layer_map->src_h);*/
6266 osd_hw.screen_base[index] = ext_addr;
6267 osd_hw.screen_size[index] =
6268 layer_map->afbc_len;
6269 }
6270 }
6271 /* just get para, need update via do_hwc */
6272 osd_hw.order[index] = layer_map->zorder;
6273 switch (layer_map->blend_mode) {
6274 case BLEND_MODE_PREMULTIPLIED:
6275 osd_hw.premult_en[index] = 1;
6276 break;
6277 case BLEND_MODE_COVERAGE:
6278 case BLEND_MODE_NONE:
6279 case BLEND_MODE_INVALID:
6280 osd_hw.premult_en[index] = 0;
6281 break;
6282 }
6283 //Todo: fence_map.plane_alpha
6284 osd_hw.osd_afbcd[index].inter_format =
6285 layer_map->afbc_inter_format & 0x7fffffff;
6286 osd_hw.osd_afbcd[index].format =
6287 color->color_index;
6288 osd_hw.src_data[index].x = layer_map->src_x;
6289 osd_hw.src_data[index].y = layer_map->src_y;
6290 osd_hw.src_data[index].w = layer_map->src_w;
6291 osd_hw.src_data[index].h = layer_map->src_h;
6292 osd_hw.dst_data[index].x = layer_map->dst_x;
6293 osd_hw.dst_data[index].y = layer_map->dst_y;
6294 osd_hw.dst_data[index].w = layer_map->dst_w;
6295 osd_hw.dst_data[index].h = layer_map->dst_h;
Googler9398cc32022-12-02 17:21:52 +08006296 osd_log_dbg(MODULE_BLEND,
6297 "osd%d src_data(x:%d y:%d w:%d h:%d)\n",
6298 index, osd_hw.src_data[index].x, osd_hw.src_data[index].y,
6299 osd_hw.src_data[index].w, osd_hw.src_data[index].h);
6300
6301 osd_log_dbg(MODULE_BLEND,
6302 "osd%d dst_data(x:%d y:%d w:%d h:%d)\n",
6303 index, osd_hw.dst_data[index].x, osd_hw.dst_data[index].y,
6304 osd_hw.dst_data[index].w, osd_hw.dst_data[index].h);
6305
6306 if (layer_map->fb_height != layer_map->src_h ||
6307 layer_map->fb_width != layer_map->src_w)
Googler9726be62022-12-14 05:53:31 +00006308 osd_hw.src_crop[index] = 1;
6309 else
6310 osd_hw.src_crop[index] = 0;
Googler4f18c0c2022-09-20 17:23:36 +08006311 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
6312 osd_hw.free_src_data[index].x_start = layer_map->src_x;
6313 osd_hw.free_src_data[index].y_start = layer_map->src_y;
6314 osd_hw.free_src_data[index].x_end =
6315 layer_map->src_x + layer_map->src_w - 1;
6316 osd_hw.free_src_data[index].y_end =
6317 layer_map->src_y + layer_map->src_h - 1;
6318 osd_hw.free_dst_data[index].x_start = layer_map->dst_x;
6319 osd_hw.free_dst_data[index].y_start = layer_map->dst_y;
6320 osd_hw.free_dst_data[index].x_end =
6321 layer_map->dst_x + layer_map->dst_w - 1;
6322 osd_hw.free_dst_data[index].y_end =
6323 layer_map->dst_y + layer_map->dst_h - 1;
6324 output_index = get_output_device_id(index);
6325 if (osd_hw.field_out_en[output_index]) {
6326 osd_hw.free_dst_data[index].y_start /= 2;
6327 osd_hw.free_dst_data[index].y_end /= 2;
6328 }
6329 }
6330 }
Googler4f18c0c2022-09-20 17:23:36 +08006331}
6332
Googler9398cc32022-12-02 17:21:52 +08006333static void check_and_reverse_axis(int start_index, int osd_count,
6334 int output_index)
6335{
6336 u32 is_reverse_disp = REVERSE_FALSE;
6337 u32 min_x = 0xffff, min_y = 0xffff, max_x = 0, max_y = 0;
6338 u32 layer_x = 0, layer_y = 0;
6339 u32 disp_range_x = 0, disp_range_y = 0;
6340 u32 pps_w_den = 1, pps_w_num = 1;
6341 u32 pps_h_den = 1, pps_h_num = 1;
6342 u32 blend_w = osd_hw.vinfo_width[output_index];
6343 u32 blend_h = osd_hw.vinfo_height[output_index];
6344 int i;
6345
6346 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL)
6347 return;
6348
6349 if (osd_hw.osd_preblend_en && output_index == VIU1) {
6350 s32 x_offset = 0, y_offset = 0;
6351
6352 blend_h = osd_hw.field_out_en[output_index] ?
6353 blend_h * 2 : blend_h;
6354 pps_w_num = osd_hw.vinfo_width[output_index];
6355 pps_w_den = osd_hw.fix_target_width;
6356 pps_h_num = blend_h;
6357 pps_h_den = osd_hw.fix_target_height;
6358 get_video_axis_offset(&x_offset, &y_offset);
6359 if (x_offset < 0)
6360 x_offset = 0;
6361 if (y_offset < 0)
6362 y_offset = 0;
6363 //pps_w_num -= 2 * x_offset;
6364 pps_h_num -= 2 * y_offset;
6365 blend_w = osd_hw.fix_target_width;
6366 blend_h = osd_hw.fix_target_height;
6367 osd_log_dbg2(MODULE_BLEND,
6368 "blend_w=%d, blend_h=%d, x_offset=%d, y_offset=%d\n",
6369 blend_w, blend_h,
6370 x_offset, y_offset);
6371 osd_hw.preblend_y_offset = y_offset * pps_h_den / pps_h_num;
6372 osd_log_dbg2(MODULE_BLEND,
6373 "osd_hw.preblend_y_offset=%d\n",
6374 osd_hw.preblend_y_offset);
6375 }
6376 osd_hw.preblend_pps_w_den = pps_w_den;
6377 osd_hw.preblend_pps_h_den = pps_h_den;
6378 osd_hw.preblend_pps_w_num = pps_w_num;
6379 osd_hw.preblend_pps_h_num = pps_h_num;
6380 /* reverse layer dst x & y */
6381 for (i = start_index; i < osd_count; i++) {
6382 if (!osd_hw.enable[i] || !validate_osd(i, output_index))
6383 continue;
6384 osd_log_dbg2(MODULE_BLEND,
6385 "osd%d orin dst(x:%d y:%d w:%d h:%d)\n",
6386 i, osd_hw.dst_data[i].x, osd_hw.dst_data[i].y,
6387 osd_hw.dst_data[i].w, osd_hw.dst_data[i].h);
6388 osd_log_dbg2(MODULE_BLEND, "pps_h_den:%d, pps_h_num=%d\n",
6389 pps_h_den, pps_h_num);
6390 osd_hw.dst_data[i].x = osd_hw.dst_data[i].x * pps_w_den / pps_w_num;
6391 osd_hw.dst_data[i].y = osd_hw.dst_data[i].y * pps_h_den / pps_h_num;
6392 osd_hw.dst_data[i].w = osd_hw.dst_data[i].w * pps_w_den / pps_w_num;
6393 osd_hw.dst_data[i].h = osd_hw.dst_data[i].h * pps_h_den / pps_h_num;
6394
6395 if (osd_hw.osd_preblend_en) {
6396 osd_log_dbg2(MODULE_BLEND,
6397 "osd%d preblend adjust dst(x:%d y:%d w:%d h:%d)\n",
6398 i, osd_hw.dst_data[i].x, osd_hw.dst_data[i].y,
6399 osd_hw.dst_data[i].w, osd_hw.dst_data[i].h);
6400 }
6401 if (min_x > osd_hw.dst_data[i].x)
6402 min_x = osd_hw.dst_data[i].x;
6403 if (min_y > osd_hw.dst_data[i].y)
6404 min_y = osd_hw.dst_data[i].y;
6405 if (max_x < (osd_hw.dst_data[i].x + osd_hw.dst_data[i].w - 1))
6406 max_x = osd_hw.dst_data[i].x + osd_hw.dst_data[i].w - 1;
6407 if (max_y < (osd_hw.dst_data[i].y + osd_hw.dst_data[i].h - 1))
6408 max_y = osd_hw.dst_data[i].y + osd_hw.dst_data[i].h - 1;
6409
6410 if (osd_hw.osd_reverse[i] == REVERSE_TRUE) {
6411 layer_x = blend_w - osd_hw.dst_data[i].x -
6412 osd_hw.dst_data[i].w;
6413 layer_y = blend_h - osd_hw.dst_data[i].y -
6414 osd_hw.dst_data[i].h;
6415 is_reverse_disp = REVERSE_TRUE;
6416 } else if (osd_hw.osd_reverse[i] == REVERSE_X) {
6417 layer_x = blend_w - osd_hw.dst_data[i].x -
6418 osd_hw.dst_data[i].w;
6419 layer_y = osd_hw.dst_data[i].y;
6420 is_reverse_disp = REVERSE_X;
6421 } else if (osd_hw.osd_reverse[i] == REVERSE_Y) {
6422 layer_x = osd_hw.dst_data[i].x;
6423 layer_y = blend_h - osd_hw.dst_data[i].y -
6424 osd_hw.dst_data[i].h;
6425 is_reverse_disp = REVERSE_Y;
6426 } else {
6427 layer_x = osd_hw.dst_data[i].x;
6428 layer_y = osd_hw.dst_data[i].y;
6429 }
6430 osd_hw.dst_data[i].x = layer_x;
6431 osd_hw.dst_data[i].y = layer_y;
6432
6433 osd_log_dbg2(MODULE_BLEND,
6434 "osd%d adjust dst(x:%d y:%d w:%d h:%d)\n",
6435 i, osd_hw.dst_data[i].x, osd_hw.dst_data[i].y,
6436 osd_hw.dst_data[i].w, osd_hw.dst_data[i].h);
6437 }
6438
6439 osd_log_dbg2(MODULE_BLEND, "orin disp position(x:%d y:%d w:%d h:%d)\n",
6440 osd_hw.disp_info[output_index].position_x,
6441 osd_hw.disp_info[output_index].position_y,
6442 osd_hw.disp_info[output_index].position_w,
6443 osd_hw.disp_info[output_index].position_h);
6444
6445 /* reverse disp position dst x & y */
6446 if (is_reverse_disp == REVERSE_TRUE) {
6447 disp_range_x = blend_w - max_x - 1;
6448 disp_range_y = blend_h - max_y - 1;
6449 } else if (is_reverse_disp == REVERSE_X) {
6450 disp_range_x = blend_w - max_x - 1;
6451 disp_range_y = min_y;
6452 } else if (is_reverse_disp == REVERSE_Y) {
6453 disp_range_x = min_x;
6454 disp_range_y = blend_h - max_y - 1;
6455 } else {
6456 disp_range_x = min_x;
6457 disp_range_y = min_y;
6458 }
6459 osd_hw.disp_info[output_index].position_x = disp_range_x;
6460 osd_hw.disp_info[output_index].position_y = disp_range_y;
6461 if (osd_hw.osd_preblend_en) {
6462 osd_hw.adjust_position_x = disp_range_x;
6463 osd_hw.adjust_position_y = disp_range_y;
6464 }
6465 osd_log_dbg2(MODULE_BLEND, "adjust disp position(x:%d y:%d w:%d h:%d)\n",
6466 osd_hw.disp_info[output_index].position_x,
6467 osd_hw.disp_info[output_index].position_y,
6468 osd_hw.disp_info[output_index].position_w,
6469 osd_hw.disp_info[output_index].position_h);
6470}
6471
6472static void _osd_pan_display_layers_fence
6473 (u32 output_index,
6474 struct vinfo_s *vinfo,
6475 struct osd_layers_fence_map_s *fence_map)
Googler4f18c0c2022-09-20 17:23:36 +08006476{
6477 int i = 0;
6478 int ret;
6479 int start_index = 0;
6480 int backup_en = 0;
6481 int osd_count = 0;
6482 /* osd_count need -1 when VIU2 enable */
6483 struct layer_fence_map_s *layer_map = NULL;
6484
6485 if (output_index == VIU1) {
6486 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
6487 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL)
6488 osd_count = 1;
6489 start_index = 0;
6490 backup_en = 1;
6491 } else if (output_index == VIU2) {
Googler9398cc32022-12-02 17:21:52 +08006492 if (osd_dev_hw.t7_display) {
6493 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
6494 start_index = 0;
6495 } else {
6496 start_index = osd_hw.osd_meson_dev.viu2_index;
6497 osd_count = start_index + 1;
6498 }
Googler4f18c0c2022-09-20 17:23:36 +08006499 backup_en = 0;
6500 } else {
Googler9398cc32022-12-02 17:21:52 +08006501 osd_log_err("invalid output_index=%d\n", output_index);
Googler4f18c0c2022-09-20 17:23:36 +08006502 return;
6503 }
6504
Googler9398cc32022-12-02 17:21:52 +08006505 if (!vinfo || !vinfo->name || (!strcmp(vinfo->name, "invalid") ||
6506 !strcmp(vinfo->name, "null"))) {
6507 if (!vinfo) {
6508 osd_log_dbg(MODULE_BASE, "vinfo is NULL\n");
6509 goto out;
6510 }
6511 if (!vinfo->name)
6512 osd_log_dbg(MODULE_BASE, "vinfo->name is NULL\n");
Googler9726be62022-12-14 05:53:31 +00006513 /* vout is null, release fence & buf file. */
6514 goto out;
Googler9398cc32022-12-02 17:21:52 +08006515 }
Googler9726be62022-12-14 05:53:31 +00006516
6517 osd_hw.vinfo_width[output_index] = vinfo->width;
6518 osd_hw.vinfo_height[output_index] = vinfo->field_height;
Googler9398cc32022-12-02 17:21:52 +08006519
Googler9726be62022-12-14 05:53:31 +00006520 memcpy(&osd_hw.disp_info[output_index], &fence_map->disp_info,
6521 sizeof(struct display_flip_info_s));
6522
Googler4f18c0c2022-09-20 17:23:36 +08006523 if (osd_hw.osd_fps_start[output_index])
6524 osd_hw.osd_fps[output_index]++;
6525 if (backup_en)
6526 clear_backup_info();
6527 osd_hw.hdr_used = fence_map->hdr_mode;
6528 for (i = start_index; i < osd_count; i++) {
Googler9398cc32022-12-02 17:21:52 +08006529 if (!validate_osd(i, output_index))
6530 continue;
Googler4f18c0c2022-09-20 17:23:36 +08006531 layer_map = &fence_map->layer_map[i];
6532 if (i != layer_map->fb_index) {
6533 osd_hw.screen_base[i] = 0;
6534 osd_hw.screen_size[i] = 0;
6535 osd_hw.enable[i] = 0;
6536 continue;
6537 }
6538 /* wait in fence */
Googler9398cc32022-12-02 17:21:52 +08006539 if (timeline_created[output_index] &&
6540 layer_map->enable &&
6541 fence_map->cmd == LAYER_SYNC) {
Googler4f18c0c2022-09-20 17:23:36 +08006542 ret = osd_wait_buf_ready_combine(layer_map);
6543 if (ret < 0)
6544 osd_log_dbg(MODULE_FENCE,
Googler9398cc32022-12-02 17:21:52 +08006545 "fence wait ret %d\n", ret);
Googler4f18c0c2022-09-20 17:23:36 +08006546 }
Googler9726be62022-12-14 05:53:31 +00006547 if (osd_hw.osd_display_debug[output_index] != OSD_DISP_DEBUG) {
6548 osd_pan_display_update_info(layer_map);
6549 if (backup_en)
6550 save_layer_info(layer_map);
6551 }
Googler4f18c0c2022-09-20 17:23:36 +08006552 }
6553 /* set hw regs */
Googler9726be62022-12-14 05:53:31 +00006554 if (osd_hw.osd_display_debug[output_index] != OSD_DISP_DEBUG)
Googler4f18c0c2022-09-20 17:23:36 +08006555 osd_setting_blend(output_index);
6556out:
6557 /* signal out fence */
6558 if (timeline_created[output_index]) {
6559 if (osd_hw.osd_debug.osd_single_step_mode) {
6560 /* single step mode */
6561 if (osd_hw.osd_debug.osd_single_step > 0) {
6562 osd_timeline_increase(output_index);
6563 osd_log_dbg(MODULE_FENCE, "signal out fence\n");
6564 osd_hw.osd_debug.osd_single_step--;
Googler9398cc32022-12-02 17:21:52 +08006565 } else {
Googler4f18c0c2022-09-20 17:23:36 +08006566 osd_hw.osd_debug.wait_fence_release = true;
Googler9398cc32022-12-02 17:21:52 +08006567 }
6568 } else {
Googler4f18c0c2022-09-20 17:23:36 +08006569 osd_timeline_increase(output_index);
Googler9398cc32022-12-02 17:21:52 +08006570 }
Googler0109c452022-10-13 17:50:39 +08006571 }
6572 /* clear osd layer's order */
6573 for (i = start_index; i < osd_count; i++) {
Googler9398cc32022-12-02 17:21:52 +08006574 if (!validate_osd(i, output_index))
6575 continue;
Googler0109c452022-10-13 17:50:39 +08006576 layer_map = &fence_map->layer_map[i];
Googler9726be62022-12-14 05:53:31 +00006577 if (displayed_bufs[i]) {
6578 fput(displayed_bufs[i]);
6579 displayed_bufs[i] = NULL;
6580 }
Googler4f18c0c2022-09-20 17:23:36 +08006581 if (layer_map->buf_file)
6582 displayed_bufs[i] = layer_map->buf_file;
6583 if (layer_map->in_fence)
6584 osd_put_fenceobj(layer_map->in_fence);
6585 osd_hw.order[i] = 0;
6586 }
6587}
6588
Googler9398cc32022-12-02 17:21:52 +08006589static void osd_pan_display_layers_fence
6590 (struct osd_layers_fence_map_s *fence_map)
Googler4f18c0c2022-09-20 17:23:36 +08006591{
6592 u32 output_index = VIU1;
6593 struct vinfo_s *vinfo = NULL;
6594
Googler9398cc32022-12-02 17:21:52 +08006595#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +08006596 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +08006597#endif
Googler4f18c0c2022-09-20 17:23:36 +08006598
6599 _osd_pan_display_layers_fence(output_index,
6600 vinfo, fence_map);
6601}
6602
Googler9398cc32022-12-02 17:21:52 +08006603static void osd_pan_display_layers_fence_viu2
6604 (struct osd_layers_fence_map_s *fence_map)
Googler4f18c0c2022-09-20 17:23:36 +08006605{
6606 u32 output_index = VIU2;
6607 struct vinfo_s *vinfo = NULL;
6608
6609#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
6610 vinfo = get_current_vinfo2();
6611#endif
6612
6613 _osd_pan_display_layers_fence(output_index,
6614 vinfo, fence_map);
6615}
6616#endif
6617
6618void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset)
6619{
6620 long diff_x, diff_y;
6621 u32 output_index;
6622
6623 if (index >= HW_OSD_COUNT)
6624 return;
6625 output_index = get_output_device_id(index);
Googler9398cc32022-12-02 17:21:52 +08006626 if (xoffset != osd_hw.pandata[index].x_start ||
6627 yoffset != osd_hw.pandata[index].y_start) {
Googler4f18c0c2022-09-20 17:23:36 +08006628 diff_x = xoffset - osd_hw.pandata[index].x_start;
6629 diff_y = yoffset - osd_hw.pandata[index].y_start;
6630 osd_hw.pandata[index].x_start += diff_x;
6631 osd_hw.pandata[index].x_end += diff_x;
6632 osd_hw.pandata[index].y_start += diff_y;
6633 osd_hw.pandata[index].y_end += diff_y;
6634 osd_hw.src_data[index].x = osd_hw.pandata[index].x_start;
6635 osd_hw.src_data[index].y = osd_hw.pandata[index].y_start;
6636 osd_hw.src_data[index].w = osd_hw.pandata[index].x_end
6637 - osd_hw.pandata[index].x_start + 1;
6638 osd_hw.src_data[index].h = osd_hw.pandata[index].y_end
6639 - osd_hw.pandata[index].y_start + 1;
6640 add_to_update_list(index, DISP_GEOMETRY);
6641 if (osd_hw.osd_fps_start[output_index])
6642 osd_hw.osd_fps[output_index]++;
6643 /* osd_wait_vsync_hw(); */
6644 }
6645#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
6646 osd_ext_clone_pan(index);
6647#endif
6648 osd_log_dbg2(MODULE_BASE, "offset[%d-%d]x[%d-%d]y[%d-%d]\n",
Googler9398cc32022-12-02 17:21:52 +08006649 xoffset, yoffset,
6650 osd_hw.pandata[index].x_start,
6651 osd_hw.pandata[index].x_end,
6652 osd_hw.pandata[index].y_start,
6653 osd_hw.pandata[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +08006654}
6655
Googler9398cc32022-12-02 17:21:52 +08006656void osd_get_info(u32 index, ulong *addr, u32 *width, u32 *height)
Googler4f18c0c2022-09-20 17:23:36 +08006657{
6658 *addr = osd_hw.fb_gem[index].addr;
6659 *width = osd_hw.fb_gem[index].width;
6660 *height = osd_hw.fb_gem[index].yres;
6661}
6662
6663static void osd_update_disp_scale_enable(u32 index)
6664{
6665 u32 osd2_cursor = 0;
6666 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
Googler9398cc32022-12-02 17:21:52 +08006667 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08006668
6669 if (osd_hw.hw_cursor_en)
6670 osd2_cursor = 1;
6671
6672 if (osd_hw.scale[index].h_enable) {
Googler9398cc32022-12-02 17:21:52 +08006673 osd_hw.osd_rdma_func[output_index].osd_rdma_set_mask
6674 (osd_reg->osd_blk0_cfg_w0, 3 << 12);
6675 if (index == OSD2 && osd2_cursor) {
6676 osd_hw.osd_rdma_func[output_index].osd_rdma_clr_mask
6677 (osd_reg->osd_blk0_cfg_w0, 3 << 12);
Googler4f18c0c2022-09-20 17:23:36 +08006678 }
Googler9398cc32022-12-02 17:21:52 +08006679 } else {
6680 osd_hw.osd_rdma_func[output_index].osd_rdma_clr_mask
6681 (osd_reg->osd_blk0_cfg_w0, 3 << 12);
6682 }
Googler4f18c0c2022-09-20 17:23:36 +08006683 if (osd_hw.scan_mode[index] != SCAN_MODE_INTERLACE) {
6684 if (osd_hw.scale[index].v_enable) {
Googler9398cc32022-12-02 17:21:52 +08006685 osd_hw.osd_rdma_func[output_index].osd_rdma_set_mask
6686 (osd_reg->osd_blk0_cfg_w0, 1 << 14);
6687 if (index == OSD2 && osd2_cursor) {
6688 osd_hw.osd_rdma_func[output_index].osd_rdma_clr_mask
6689 (osd_reg->osd_blk0_cfg_w0, 1 << 14);
Googler4f18c0c2022-09-20 17:23:36 +08006690 }
Googler9398cc32022-12-02 17:21:52 +08006691 } else {
6692 osd_hw.osd_rdma_func[output_index].osd_rdma_clr_mask
6693 (osd_reg->osd_blk0_cfg_w0, 1 << 14);
6694 }
Googler4f18c0c2022-09-20 17:23:36 +08006695 }
6696 remove_from_update_list(index, DISP_SCALE_ENABLE);
6697}
6698
6699static void osd_set_dummy_data(u32 index, u32 alpha)
6700{
Googler9398cc32022-12-02 17:21:52 +08006701 u32 output_index = get_output_device_id(index);
6702
6703 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6704 (hw_osd_reg_array[index].osd_sc_dummy_data,
Googler9726be62022-12-14 05:53:31 +00006705 osd_hw.osd_meson_dev.dummy_data | alpha);
6706}
6707
Googler4f18c0c2022-09-20 17:23:36 +08006708static void osd_update_disp_freescale_enable(u32 index)
6709{
Googler9726be62022-12-14 05:53:31 +00006710 u64 hf_phase_step, vf_phase_step;
Googler4f18c0c2022-09-20 17:23:36 +08006711 int src_w, src_h, dst_w, dst_h;
6712 int bot_ini_phase, top_ini_phase;
6713 int vsc_ini_rcv_num, vsc_ini_rpt_p0_num;
6714 int vsc_bot_rcv_num = 0, vsc_bot_rpt_p0_num = 0;
6715 int hsc_ini_rcv_num, hsc_ini_rpt_p0_num;
6716 int hf_bank_len = 4;
6717 int vf_bank_len = 4;
6718 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
6719 u32 data32 = 0x0;
6720 u32 shift_workaround = 0;
6721 u32 output_index = 0;
6722
6723 if (osd_hw.osd_meson_dev.osd_ver != OSD_HIGH_ONE)
6724 osd_reg = &hw_osd_reg_array[0];
6725
Googler9398cc32022-12-02 17:21:52 +08006726 if (osd_hw.scale_workaround)
Googler4f18c0c2022-09-20 17:23:36 +08006727 vf_bank_len = 2;
6728 else
6729 vf_bank_len = 4;
6730
6731 output_index = get_output_device_id(index);
Googler9398cc32022-12-02 17:21:52 +08006732 if (osd_hw.hwc_enable[output_index] && index == OSD1)
Googler4f18c0c2022-09-20 17:23:36 +08006733 shift_workaround = osd_hw.workaround_line;
6734
6735#ifndef NEW_PPS_PHASE
6736 if (osd_hw.bot_type == 1) {
6737 vsc_bot_rcv_num = 4;
6738 vsc_bot_rpt_p0_num = 1;
6739 } else if (osd_hw.bot_type == 2) {
6740 vsc_bot_rcv_num = 6;
6741 vsc_bot_rpt_p0_num = 2;
6742 } else if (osd_hw.bot_type == 3) {
6743 vsc_bot_rcv_num = 8;
6744 vsc_bot_rpt_p0_num = 3;
6745 }
6746 vsc_ini_rcv_num = vf_bank_len;
6747 vsc_ini_rpt_p0_num =
6748 (vf_bank_len / 2 - 1) > 0 ? (vf_bank_len / 2 - 1) : 0;
6749#endif
6750
6751 hsc_ini_rcv_num = hf_bank_len;
6752 hsc_ini_rpt_p0_num = hf_bank_len / 2 - 1;
6753
6754 src_w = osd_hw.free_src_data[index].x_end -
6755 osd_hw.free_src_data[index].x_start + 1;
6756 src_h = osd_hw.free_src_data[index].y_end -
6757 osd_hw.free_src_data[index].y_start + 1;
6758 dst_w = osd_hw.free_dst_data[index].x_end -
6759 osd_hw.free_dst_data[index].x_start + 1;
6760 dst_h = osd_hw.free_dst_data[index].y_end -
6761 osd_hw.free_dst_data[index].y_start + 1;
Googler9398cc32022-12-02 17:21:52 +08006762
Googler4f18c0c2022-09-20 17:23:36 +08006763 /* config osd sc control reg */
6764 data32 = 0x0;
6765 if (osd_hw.free_scale_enable[index]) {
6766 /* enable osd scaler */
6767 if (osd_hw.free_scale_mode[index] & 0x1) {
6768 /* Todo: */
6769 if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL)
6770 data32 |= index; /* select osd1/2 input */
6771 /* Todo: vd alpha */
6772 data32 |= 1 << 2; /* enable osd scaler */
6773 data32 |= 1 << 3; /* enable osd scaler path */
Googler9398cc32022-12-02 17:21:52 +08006774 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6775 (osd_reg->osd_sc_ctrl0,
6776 data32);
Googler4f18c0c2022-09-20 17:23:36 +08006777 }
6778 } else {
6779 /* disable osd scaler path */
Googler9398cc32022-12-02 17:21:52 +08006780 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6781 (osd_reg->osd_sc_ctrl0, 0);
Googler4f18c0c2022-09-20 17:23:36 +08006782 }
6783
Googler9726be62022-12-14 05:53:31 +00006784 hf_phase_step = (u64)src_w << 24;
Googler9398cc32022-12-02 17:21:52 +08006785 if (dst_w == 0)
6786 dst_w = 1;
Googler9726be62022-12-14 05:53:31 +00006787 do_div(hf_phase_step, dst_w);
6788 if (shift_workaround) {
6789 vf_phase_step = (u64)(src_h - 1) << 20;
Googler9398cc32022-12-02 17:21:52 +08006790 if (dst_h == 0)
6791 dst_h = 1;
Googler9726be62022-12-14 05:53:31 +00006792 do_div(vf_phase_step, dst_h);
6793 } else {
6794 vf_phase_step = (u64)src_h << 20;
Googler9398cc32022-12-02 17:21:52 +08006795 if (dst_h == 0)
6796 dst_h = 1;
Googler9726be62022-12-14 05:53:31 +00006797 do_div(vf_phase_step, dst_h);
6798 }
Googler4f18c0c2022-09-20 17:23:36 +08006799
6800#ifdef NEW_PPS_PHASE
Googler9398cc32022-12-02 17:21:52 +08006801 if (osd_hw.field_out_en[output_index]) {
Googler4f18c0c2022-09-20 17:23:36 +08006802 struct osd_f2v_vphase_s vphase;
6803
Googler9398cc32022-12-02 17:21:52 +08006804 f2v_get_vertical_phase(vf_phase_step,
6805 OSD_F2V_P2IT,
6806 vf_bank_len,
6807 &vphase);
Googler4f18c0c2022-09-20 17:23:36 +08006808 vsc_ini_rcv_num = vphase.rcv_num;
6809 vsc_ini_rpt_p0_num = vphase.rpt_num;
6810 top_ini_phase = vphase.phase;
6811
Googler9398cc32022-12-02 17:21:52 +08006812 f2v_get_vertical_phase(vf_phase_step,
6813 OSD_F2V_P2IB,
6814 vf_bank_len,
6815 &vphase);
Googler4f18c0c2022-09-20 17:23:36 +08006816 vsc_bot_rcv_num = vphase.rcv_num;
6817 vsc_bot_rpt_p0_num = vphase.rpt_num;
6818 bot_ini_phase = vphase.phase;
6819 } else {
6820 struct osd_f2v_vphase_s vphase;
6821
Googler9398cc32022-12-02 17:21:52 +08006822 f2v_get_vertical_phase(vf_phase_step,
6823 OSD_F2V_P2P,
6824 vf_bank_len,
6825 &vphase);
Googler4f18c0c2022-09-20 17:23:36 +08006826 vsc_ini_rcv_num = vphase.rcv_num;
6827 vsc_ini_rpt_p0_num = vphase.rpt_num;
6828 top_ini_phase = vphase.phase;
6829
6830 vsc_bot_rcv_num = 0;
6831 vsc_bot_rpt_p0_num = 0;
6832 bot_ini_phase = 0;
6833 }
6834#else
Googler9398cc32022-12-02 17:21:52 +08006835 if (osd_hw.field_out_en[output_index]) /* interface output */
Googler4f18c0c2022-09-20 17:23:36 +08006836 bot_ini_phase = ((vf_phase_step / 2) >> 4);
6837 else
6838 bot_ini_phase = 0;
6839 top_ini_phase = 0;
6840#endif
6841
6842 vf_phase_step = (vf_phase_step << 4);
6843 /* config osd scaler in/out hv size */
6844 data32 = 0x0;
6845 if (shift_workaround) {
6846 vsc_ini_rcv_num++;
Googler9398cc32022-12-02 17:21:52 +08006847 if (osd_hw.field_out_en[output_index])
Googler4f18c0c2022-09-20 17:23:36 +08006848 vsc_bot_rcv_num++;
6849 }
6850
Googler4f18c0c2022-09-20 17:23:36 +08006851 if (osd_hw.free_scale_enable[index]) {
6852 data32 = (((src_h - 1) & 0x1fff)
6853 | ((src_w - 1) & 0x1fff) << 16);
Googler9398cc32022-12-02 17:21:52 +08006854 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6855 (osd_reg->osd_sci_wh_m1, data32);
Googler4f18c0c2022-09-20 17:23:36 +08006856 data32 = ((osd_hw.free_dst_data[index].x_end & 0xfff) |
6857 (osd_hw.free_dst_data[index].x_start & 0xfff) << 16);
Googler9398cc32022-12-02 17:21:52 +08006858 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6859 (osd_reg->osd_sco_h_start_end, data32);
Googler4f18c0c2022-09-20 17:23:36 +08006860 data32 = ((osd_hw.free_dst_data[index].y_end & 0xfff) |
6861 (osd_hw.free_dst_data[index].y_start & 0xfff) << 16);
Googler9398cc32022-12-02 17:21:52 +08006862 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6863 (osd_reg->osd_sco_v_start_end, data32);
Googler4f18c0c2022-09-20 17:23:36 +08006864 }
Googler9398cc32022-12-02 17:21:52 +08006865
Googler4f18c0c2022-09-20 17:23:36 +08006866 data32 = 0x0;
6867 if (osd_hw.free_scale[index].v_enable) {
6868 data32 |= (vf_bank_len & 0x7)
6869 | ((vsc_ini_rcv_num & 0xf) << 3)
6870 | ((vsc_ini_rpt_p0_num & 0x3) << 8);
Googler9398cc32022-12-02 17:21:52 +08006871 if (osd_hw.field_out_en[output_index])
Googler4f18c0c2022-09-20 17:23:36 +08006872 data32 |= ((vsc_bot_rcv_num & 0xf) << 11)
6873 | ((vsc_bot_rpt_p0_num & 0x3) << 16)
6874 | (1 << 23);
Googler9398cc32022-12-02 17:21:52 +08006875 if (osd_hw.scale_workaround)
Googler4f18c0c2022-09-20 17:23:36 +08006876 data32 |= 1 << 21;
6877 data32 |= 1 << 24;
6878 if (osd_hw.osd_meson_dev.cpu_id >=
6879 __MESON_CPU_MAJOR_ID_G12B)
6880 data32 |= 1 << 25;
6881 }
Googler9398cc32022-12-02 17:21:52 +08006882 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6883 (osd_reg->osd_vsc_ctrl0, data32);
Googler4f18c0c2022-09-20 17:23:36 +08006884 data32 = 0x0;
6885 if (osd_hw.free_scale[index].h_enable) {
6886 data32 |= (hf_bank_len & 0x7)
6887 | ((hsc_ini_rcv_num & 0xf) << 3)
6888 | ((hsc_ini_rpt_p0_num & 0x3) << 8);
6889 data32 |= 1 << 22;
6890 }
Googler9398cc32022-12-02 17:21:52 +08006891 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6892 (osd_reg->osd_hsc_ctrl0, data32);
Googler4f18c0c2022-09-20 17:23:36 +08006893
6894 data32 = top_ini_phase;
6895 if (osd_hw.free_scale_enable[index]) {
6896 data32 |= (bot_ini_phase & 0xffff) << 16;
Googler9398cc32022-12-02 17:21:52 +08006897 if (osd_hw.field_out_en[output_index]) {
Googler9726be62022-12-14 05:53:31 +00006898 if (shift_workaround)
6899 src_h--;
6900 if (src_h == dst_h * 2)
6901 data32 |= 0x80008000;
6902 }
Googler9398cc32022-12-02 17:21:52 +08006903 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
6904 (osd_reg->osd_hsc_phase_step,
Googler9726be62022-12-14 05:53:31 +00006905 hf_phase_step, 0, 28);
Googler9398cc32022-12-02 17:21:52 +08006906 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
6907 (osd_reg->osd_hsc_init_phase,
6908 0, 0, 16);
6909 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
6910 (osd_reg->osd_vsc_phase_step,
Googler9726be62022-12-14 05:53:31 +00006911 vf_phase_step, 0, 28);
Googler9398cc32022-12-02 17:21:52 +08006912 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
6913 (osd_reg->osd_vsc_init_phase,
6914 data32);
Googler4f18c0c2022-09-20 17:23:36 +08006915 }
Googler9398cc32022-12-02 17:21:52 +08006916 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE &&
6917 !osd_hw.hwc_enable[output_index]) {
Googler4f18c0c2022-09-20 17:23:36 +08006918 osd_setting_blending_scope(index);
6919 vpp_blend_setting_default(index);
6920 }
6921
6922 remove_from_update_list(index, DISP_FREESCALE_ENABLE);
6923}
6924
Googler4f18c0c2022-09-20 17:23:36 +08006925static void osd_update_coef(u32 index)
6926{
6927 int i;
6928 bool need_update_coef = false;
6929 int *hf_coef, *vf_coef;
6930 int use_v_filter_mode, use_h_filter_mode;
6931 int OSD_SCALE_COEF_IDX, OSD_SCALE_COEF;
6932
6933 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
6934 OSD_SCALE_COEF_IDX =
6935 hw_osd_reg_array[index].osd_scale_coef_idx;
6936 OSD_SCALE_COEF =
6937 hw_osd_reg_array[index].osd_scale_coef;
6938 } else {
6939 OSD_SCALE_COEF_IDX =
6940 hw_osd_reg_array[0].osd_scale_coef_idx;
6941 OSD_SCALE_COEF =
6942 hw_osd_reg_array[0].osd_scale_coef;
6943 }
6944 use_v_filter_mode = osd_hw.use_v_filter_mode[index];
6945 use_h_filter_mode = osd_hw.use_h_filter_mode[index];
Googler9398cc32022-12-02 17:21:52 +08006946 if (osd_hw.scale_workaround) {
Googler4f18c0c2022-09-20 17:23:36 +08006947 if (use_v_filter_mode != 3) {
6948 use_v_filter_mode = 3;
6949 need_update_coef = true;
Googler9398cc32022-12-02 17:21:52 +08006950 } else {
Googler4f18c0c2022-09-20 17:23:36 +08006951 need_update_coef = false;
Googler9398cc32022-12-02 17:21:52 +08006952 }
Googler4f18c0c2022-09-20 17:23:36 +08006953 } else {
6954 if (use_v_filter_mode != osd_v_filter_mode) {
6955 use_v_filter_mode = osd_v_filter_mode;
6956 need_update_coef = true;
Googler9398cc32022-12-02 17:21:52 +08006957 } else {
Googler4f18c0c2022-09-20 17:23:36 +08006958 need_update_coef = false;
Googler9398cc32022-12-02 17:21:52 +08006959 }
Googler4f18c0c2022-09-20 17:23:36 +08006960 }
6961 if (need_update_coef) {
6962 vf_coef = filter_table[use_v_filter_mode];
6963 osd_reg_set_bits(OSD_SCALE_COEF_IDX, 0x0000, 0, 9);
6964 for (i = 0; i < 33; i++)
6965 osd_reg_write(OSD_SCALE_COEF, vf_coef[i]);
6966 }
6967 need_update_coef = false;
6968 if (use_h_filter_mode != osd_h_filter_mode) {
6969 use_h_filter_mode = osd_h_filter_mode;
6970 need_update_coef = true;
6971 }
6972 hf_coef = filter_table[use_h_filter_mode];
6973 if (need_update_coef) {
6974 osd_reg_set_bits(OSD_SCALE_COEF_IDX, 0x0100, 0, 9);
6975 for (i = 0; i < 33; i++)
6976 osd_reg_write(OSD_SCALE_COEF, hf_coef[i]);
6977 }
6978 osd_hw.use_v_filter_mode[index] = use_v_filter_mode;
6979 osd_hw.use_h_filter_mode[index] = use_h_filter_mode;
6980
6981 remove_from_update_list(index, OSD_FREESCALE_COEF);
6982}
6983
6984static int afbc_pix_format(u32 fmt_mode)
6985{
6986 u32 pix_format = RGBA8888;
6987
6988 switch (fmt_mode) {
6989 case COLOR_INDEX_YUV_422:
6990 pix_format = YUV422_8B;
6991 break;
6992 case COLOR_INDEX_16_565:
6993 pix_format = RGB565;
6994 break;
6995 case COLOR_INDEX_16_1555_A:
6996 pix_format = RGBA5551;
6997 break;
6998 case COLOR_INDEX_16_4444_R:
6999 case COLOR_INDEX_16_4444_A:
7000 pix_format = RGBA4444;
7001 break;
7002 case COLOR_INDEX_32_BGRX:
7003 case COLOR_INDEX_32_XBGR:
7004 case COLOR_INDEX_32_RGBX:
7005 case COLOR_INDEX_32_XRGB:
7006 case COLOR_INDEX_32_BGRA:
7007 case COLOR_INDEX_32_ABGR:
7008 case COLOR_INDEX_32_RGBA:
7009 case COLOR_INDEX_32_ARGB:
7010 pix_format = RGBA8888;
7011 break;
7012 case COLOR_INDEX_24_888_B:
7013 case COLOR_INDEX_24_RGB:
7014 pix_format = RGB888;
7015 break;
7016 case COLOR_INDEX_RGBA_1010102:
7017 pix_format = RGBA1010102;
7018 break;
7019 default:
7020 osd_log_err("unsupport fmt:%x\n", fmt_mode);
7021 break;
7022 }
7023 return pix_format;
7024}
7025
Googler4f18c0c2022-09-20 17:23:36 +08007026static void osd_update_color_mode(u32 index)
7027{
7028 u32 data32 = 0;
7029 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
Googler9398cc32022-12-02 17:21:52 +08007030 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08007031
Googler9398cc32022-12-02 17:21:52 +08007032 if (osd_hw.color_info[index]) {
Googler4f18c0c2022-09-20 17:23:36 +08007033 enum color_index_e idx =
7034 osd_hw.color_info[index]->color_index;
7035
7036 data32 = (osd_hw.scan_mode[index] ==
7037 SCAN_MODE_INTERLACE) ? 2 : 0;
Googler9398cc32022-12-02 17:21:52 +08007038 data32 |= osd_hw.osd_rdma_func[output_index].osd_rdma_rd
7039 (osd_reg->osd_blk0_cfg_w0)
Googler4f18c0c2022-09-20 17:23:36 +08007040 & 0x70007040;
7041 data32 |= osd_hw.fb_gem[index].canvas_idx << 16;
Googler9398cc32022-12-02 17:21:52 +08007042 if (osd_hw.osd_afbcd[index].enable &&
7043 osd_hw.osd_meson_dev.afbc_type == MALI_AFBC)
Googler4f18c0c2022-09-20 17:23:36 +08007044 data32 |= OSD_DATA_BIG_ENDIAN << 15;
7045 else
7046 data32 |= OSD_DATA_LITTLE_ENDIAN << 15;
7047 data32 |= osd_hw.color_info[index]->hw_colormat << 2;
7048
7049 /* Todo: what about osd3 */
Googler9398cc32022-12-02 17:21:52 +08007050#ifndef CONFIG_AMLOGIC_REMOVE_OLD
7051 if (osd_hw.osd_meson_dev.cpu_id <
7052 __MESON_CPU_MAJOR_ID_GXTVBB &&
7053 index == OSD1) {
Googler4f18c0c2022-09-20 17:23:36 +08007054 if (osd_hw.color_info[index]->color_index <
7055 COLOR_INDEX_YUV_422)
7056 data32 |= 1 << 7; /* yuv enable */
7057 }
Googler9398cc32022-12-02 17:21:52 +08007058#endif
7059 if (osd_hw.osd_meson_dev.cpu_id !=
7060 __MESON_CPU_MAJOR_ID_GXTVBB &&
7061 index == OSD2) {
Googler4f18c0c2022-09-20 17:23:36 +08007062 if (osd_hw.color_info[index]->color_index <
7063 COLOR_INDEX_YUV_422)
7064 data32 |= 1 << 7; /* yuv enable */
7065 }
7066 /* osd_blk_mode */
7067 data32 |= osd_hw.color_info[index]->hw_blkmode << 8;
Googler9726be62022-12-14 05:53:31 +00007068 if (osd_hw.osd_v_skip[index])
7069 data32 |= 1 << 24;
Googler9398cc32022-12-02 17:21:52 +08007070 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7071 (osd_reg->osd_blk0_cfg_w0, data32);
Googler9726be62022-12-14 05:53:31 +00007072
Googler4f18c0c2022-09-20 17:23:36 +08007073 /*
7074 * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0, data32);
7075 * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0, data32);
7076 * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0, data32);
7077 */
7078 if (osd_hw.osd_afbcd[index].enable) {
7079 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
7080 /* only the RGBA32 mode */
Googler9398cc32022-12-02 17:21:52 +08007081 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7082 (OSD1_AFBCD_MODE,
7083 (3 << 24) |
7084 (4 << 16) |
7085 (0xe4 << 8) |
7086 (1 << 6) |
7087 (1 << 5) |
7088 (0x15 << 0));
Googler4f18c0c2022-09-20 17:23:36 +08007089 /* TODO: add pixel_packing_fmt setting */
Googler9398cc32022-12-02 17:21:52 +08007090 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7091 (OSD1_AFBCD_CONV_CTRL,
7092 osd_hw.osd_afbcd[index].conv_lbuf_len
7093 & 0xffff);
Googler4f18c0c2022-09-20 17:23:36 +08007094 /* afbc mode RGBA32 -> RGB24
7095 * data32 = (0x1b << 24) |
7096 * (osd_hw.osd_afbcd[OSD1].phy_addr
7097 * & 0xffffff);
7098 * VSYNCOSD_WR_MPEG_REG(
7099 * OSD1_AFBCD_CHROMA_PTR,
7100 * data32);
7101 */
Googler9398cc32022-12-02 17:21:52 +08007102 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7103 (OSD1_AFBCD_CHROMA_PTR, 0xe4, 24, 8);
Googler4f18c0c2022-09-20 17:23:36 +08007104 /*
7105 * data32 = (0xe4 << 24) |
7106 * (osd_hw.osd_afbcd[OSD1].phy_addr
7107 * & 0xffffff);
7108 * VSYNCOSD_WR_MPEG_REG(
7109 * OSD1_AFBCD_CHROMA_PTR,
7110 * data32);
7111 */
Googler9398cc32022-12-02 17:21:52 +08007112 } else if (osd_hw.osd_meson_dev.afbc_type ==
7113 MALI_AFBC) {
Googler4f18c0c2022-09-20 17:23:36 +08007114 u32 bpp, pixel_format;
7115 u32 line_stride, output_stride;
7116 u32 aligned_32 = 1; /* need get from hwc line */
Googler4f18c0c2022-09-20 17:23:36 +08007117 u32 afbc_color_reorder = 0x1234;
7118 /* 0x4321 = ABGR
7119 * 0x1234 = RGBA
7120 */
Googler9398cc32022-12-02 17:21:52 +08007121 pixel_format = afbc_pix_format
7122 (osd_hw.osd_afbcd[index].format);
Googler4f18c0c2022-09-20 17:23:36 +08007123 bpp = osd_hw.color_info[index]->bpp >> 3;
Googler9398cc32022-12-02 17:21:52 +08007124 line_stride = line_stride_calc_afbc
7125 (pixel_format,
Googler4f18c0c2022-09-20 17:23:36 +08007126 osd_hw.osd_afbcd[index].frame_width,
7127 aligned_32);
Googler9398cc32022-12-02 17:21:52 +08007128 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7129 (osd_reg->afbc_format_specifier_s,
Googler4f18c0c2022-09-20 17:23:36 +08007130 (osd_hw.osd_afbcd[index].inter_format |
7131 (pixel_format & 0xf)));
Googler9398cc32022-12-02 17:21:52 +08007132 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7133 (osd_reg->osd_mali_unpack_ctrl,
Googler4f18c0c2022-09-20 17:23:36 +08007134 afbc_color_reorder,
7135 0, 16);
Googler9398cc32022-12-02 17:21:52 +08007136 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7137 (osd_reg->osd_blk2_cfg_w4,
Googler4f18c0c2022-09-20 17:23:36 +08007138 line_stride, 0, 12);
7139 output_stride =
7140 osd_hw.osd_afbcd[index].frame_width
7141 * bpp;
Googler9398cc32022-12-02 17:21:52 +08007142 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7143 (osd_reg->afbc_output_buf_stride_s,
Googler4f18c0c2022-09-20 17:23:36 +08007144 output_stride);
7145 }
7146 } else {
7147 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
Googler9398cc32022-12-02 17:21:52 +08007148 if (!osd_hw.osd_meson_dev.mif_linear)
7149 /* line stride should not clear for mif */
7150 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7151 (osd_reg->osd_blk2_cfg_w4, 0);
Googler4f18c0c2022-09-20 17:23:36 +08007152 }
7153 }
Googler9398cc32022-12-02 17:21:52 +08007154 if ((idx >= COLOR_INDEX_32_BGRX &&
7155 idx <= COLOR_INDEX_32_XRGB) ||
7156 (idx >= COLOR_INDEX_32_BGRA &&
7157 idx <= COLOR_INDEX_32_ARGB &&
7158 osd_hw.blend_mode[index] == BLEND_MODE_NONE))
7159 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7160 (osd_reg->osd_ctrl_stat2,
Googler9726be62022-12-14 05:53:31 +00007161 0x1ff, 6, 9);
Googler4f18c0c2022-09-20 17:23:36 +08007162 else
Googler9398cc32022-12-02 17:21:52 +08007163 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7164 (osd_reg->osd_ctrl_stat2,
Googler9726be62022-12-14 05:53:31 +00007165 0, 6, 9);
Googler4f18c0c2022-09-20 17:23:36 +08007166 }
7167 remove_from_update_list(index, OSD_COLOR_MODE);
7168}
7169
Googler4f18c0c2022-09-20 17:23:36 +08007170static void osd_update_enable(u32 index)
7171{
Googler9398cc32022-12-02 17:21:52 +08007172 u32 temp_val = 0, output_index;
Googler4f18c0c2022-09-20 17:23:36 +08007173 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
7174
Googler9398cc32022-12-02 17:21:52 +08007175 output_index = get_output_device_id(index);
7176
7177 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC &&
7178 osd_hw.enable[index] == ENABLE) {
Googler4f18c0c2022-09-20 17:23:36 +08007179 /* only for osd1 */
Googler9398cc32022-12-02 17:21:52 +08007180 if ((osd_hw.osd_rdma_func[output_index].osd_rdma_rd
7181 (VPU_RDARB_MODE_L1C2) &
Googler4f18c0c2022-09-20 17:23:36 +08007182 (1 << 16)) == 0) {
Googler9398cc32022-12-02 17:21:52 +08007183 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7184 (VPU_RDARB_MODE_L1C2,
7185 1, 16, 1);
Googler4f18c0c2022-09-20 17:23:36 +08007186 }
7187 }
7188 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
7189 if (index == OSD1)
7190 temp_val = VPP_OSD1_POSTBLEND;
7191 else if (index == OSD2)
7192 temp_val = VPP_OSD2_POSTBLEND;
7193 if (osd_hw.enable[index] == ENABLE)
7194 osd_vpp_misc |= temp_val;
7195 else
7196 osd_vpp_misc &= ~temp_val;
Googler4f18c0c2022-09-20 17:23:36 +08007197 }
7198 if (osd_hw.enable[index] == ENABLE) {
Googler9398cc32022-12-02 17:21:52 +08007199 osd_hw.osd_rdma_func[output_index].osd_rdma_set_mask
7200 (osd_reg->osd_ctrl_stat,
7201 1 << 0);
Googler4f18c0c2022-09-20 17:23:36 +08007202 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
Googler9398cc32022-12-02 17:21:52 +08007203 osd_hw.osd_rdma_func[output_index].osd_rdma_set_mask
7204 (VPP_MISC,
7205 temp_val |
7206 VPP_POSTBLEND_EN);
Googler4f18c0c2022-09-20 17:23:36 +08007207 notify_to_amvideo();
Googler9398cc32022-12-02 17:21:52 +08007208 } else {
7209 /* notify osd_vpp1_bld_ctrl and osd_vpp2_bld_ctrl */
7210 if (get_output_device_id(index) != VPP0)
7211 notify_to_amvideo();
Googler4f18c0c2022-09-20 17:23:36 +08007212 }
Googler9398cc32022-12-02 17:21:52 +08007213
Googler4f18c0c2022-09-20 17:23:36 +08007214 } else {
7215 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
7216 notify_to_amvideo();
Googler9398cc32022-12-02 17:21:52 +08007217 osd_hw.osd_rdma_func[output_index].osd_rdma_clr_mask
7218 (VPP_MISC, temp_val);
7219 } else {
7220 if (get_output_device_id(index) != VPP0)
7221 notify_to_amvideo();
Googler4f18c0c2022-09-20 17:23:36 +08007222 }
7223 if (!(osd_hw.osd_meson_dev.cpu_id ==
7224 __MESON_CPU_MAJOR_ID_G12B))
Googler9398cc32022-12-02 17:21:52 +08007225 osd_hw.osd_rdma_func[output_index].osd_rdma_clr_mask
7226 (osd_reg->osd_ctrl_stat,
7227 1 << 0);
Googler4f18c0c2022-09-20 17:23:36 +08007228 }
7229 if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
Googler9398cc32022-12-02 17:21:52 +08007230 if (osd_hw.osd_afbcd[index].enable == ENABLE &&
7231 osd_hw.enable[index] == ENABLE) {
Googler4f18c0c2022-09-20 17:23:36 +08007232 if (!osd_afbc_dec_enable &&
Googler9398cc32022-12-02 17:21:52 +08007233 osd_hw.osd_afbcd[index].phy_addr != 0) {
7234 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7235 (OSD1_AFBCD_ENABLE, 0x8100);
Googler4f18c0c2022-09-20 17:23:36 +08007236 osd_afbc_dec_enable = 1;
7237 }
Googler9398cc32022-12-02 17:21:52 +08007238 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7239 (osd_reg->osd_ctrl_stat2,
7240 1, 15, 1);
7241 if ((osd_hw.osd_rdma_func[output_index].osd_rdma_rd
7242 (VIU_MISC_CTRL1) &
7243 (0xff << 8)) != 0x9000) {
7244 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7245 (VIU_MISC_CTRL1,
7246 0x90, 8, 8);
Googler9726be62022-12-14 05:53:31 +00007247 }
Googler4f18c0c2022-09-20 17:23:36 +08007248 } else {
7249 if (osd_afbc_dec_enable) {
Googler9398cc32022-12-02 17:21:52 +08007250 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7251 (OSD1_AFBCD_ENABLE, 0x8000);
Googler4f18c0c2022-09-20 17:23:36 +08007252 osd_afbc_dec_enable = 0;
7253 }
Googler9398cc32022-12-02 17:21:52 +08007254 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7255 (osd_reg->osd_ctrl_stat2,
7256 0, 15, 1);
Googler4f18c0c2022-09-20 17:23:36 +08007257 }
7258 } else if (osd_hw.osd_meson_dev.afbc_type
7259 == MALI_AFBC) {
Googler9398cc32022-12-02 17:21:52 +08007260 if (osd_hw.osd_afbcd[index].enable == ENABLE &&
7261 osd_hw.enable[index] == ENABLE &&
7262 !osd_hw.dim_layer[index]) {
Googler9726be62022-12-14 05:53:31 +00007263 if (!osd_hw.osd_afbcd[index].afbc_start &&
Googler9398cc32022-12-02 17:21:52 +08007264 osd_hw.osd_afbcd[index].phy_addr != 0) {
Googler9726be62022-12-14 05:53:31 +00007265 /* enable mali afbc */
Googler9398cc32022-12-02 17:21:52 +08007266 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7267 (osd_reg->vpu_mafbc_irq_mask, 0xf);
7268 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7269 (osd_reg->vpu_mafbc_surface_cfg,
7270 0x1, index, 1);
Googler9726be62022-12-14 05:53:31 +00007271 osd_hw.osd_afbcd[index].afbc_start = 1;
Googler9398cc32022-12-02 17:21:52 +08007272 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7273 (osd_reg->osd_ctrl_stat2,
7274 1, 1, 1);
Googler9726be62022-12-14 05:53:31 +00007275 }
Googler4f18c0c2022-09-20 17:23:36 +08007276 } else {
7277 /* disable mali afbc */
Googler9398cc32022-12-02 17:21:52 +08007278 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7279 (osd_reg->vpu_mafbc_surface_cfg,
7280 0x0, index, 1);
Googler4f18c0c2022-09-20 17:23:36 +08007281 osd_hw.osd_afbcd[index].afbc_start = 0;
Googler9398cc32022-12-02 17:21:52 +08007282 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7283 (osd_reg->osd_ctrl_stat2,
7284 0, 1, 1);
Googler4f18c0c2022-09-20 17:23:36 +08007285 }
Googler4f18c0c2022-09-20 17:23:36 +08007286 }
Googler9398cc32022-12-02 17:21:52 +08007287 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE &&
7288 osd_hw.hwc_enable[output_index]) {
Googler4f18c0c2022-09-20 17:23:36 +08007289 u8 postbld_src_sel = 0;
Googler9398cc32022-12-02 17:21:52 +08007290 u8 postbld_osd1, postbld_osd2;
Googler4f18c0c2022-09-20 17:23:36 +08007291
Googler9398cc32022-12-02 17:21:52 +08007292 if (osd_hw.enable[index] == ENABLE) {
7293 if (osd_dev_hw.t7_display) {
7294 postbld_osd1 = POSTBLD_OSD1_T7;
7295 postbld_osd2 = POSTBLD_OSD2_T7;
7296 } else {
7297 postbld_osd1 = POSTBLD_OSD1;
7298 postbld_osd2 = POSTBLD_OSD2;
7299 }
7300 postbld_src_sel = (index == 0) ? postbld_osd1 : postbld_osd2;
7301 }
Googler4f18c0c2022-09-20 17:23:36 +08007302 if (index == 0)
Googler9398cc32022-12-02 17:21:52 +08007303 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7304 (OSD1_BLEND_SRC_CTRL,
7305 (0 & 0xf) << 0 |
7306 (0 & 0x1) << 4 |
7307 (postbld_src_sel & 0xf) << 8 |
7308 (0 & 0x1) << 16 |
7309 (1 & 0x1) << 20);
Googler4f18c0c2022-09-20 17:23:36 +08007310 else if ((index == 1) && (!enable_vd_zorder))
Googler9398cc32022-12-02 17:21:52 +08007311 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7312 (OSD2_BLEND_SRC_CTRL,
7313 (0 & 0xf) << 0 |
7314 (0 & 0x1) << 4 |
7315 (postbld_src_sel & 0xf) << 8 |
7316 (0 & 0x1) << 16 |
7317 (1 & 0x1) << 20);
Googler4f18c0c2022-09-20 17:23:36 +08007318 }
7319 remove_from_update_list(index, OSD_ENABLE);
7320}
7321
7322static void osd_update_disp_osd_reverse(u32 index)
7323{
Googler9398cc32022-12-02 17:21:52 +08007324 u32 output_index = get_output_device_id(index);
7325
Googler4f18c0c2022-09-20 17:23:36 +08007326 if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
Googler9398cc32022-12-02 17:21:52 +08007327 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7328 (hw_osd_reg_array[index].osd_blk0_cfg_w0, 3, 28, 2);
7329 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
7330 osd_hw.osd_afbcd[index].enable == ENABLE)
7331 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7332 (hw_osd_reg_array[index].afbc_prefetch_cfg_s, 3, 0, 2);
Googler4f18c0c2022-09-20 17:23:36 +08007333 } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
Googler9398cc32022-12-02 17:21:52 +08007334 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7335 (hw_osd_reg_array[index].osd_blk0_cfg_w0, 1, 28, 2);
7336 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
7337 osd_hw.osd_afbcd[index].enable == ENABLE)
7338 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7339 (hw_osd_reg_array[index].afbc_prefetch_cfg_s,
7340 1, 0, 2);
Googler4f18c0c2022-09-20 17:23:36 +08007341 } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
Googler9398cc32022-12-02 17:21:52 +08007342 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7343 (hw_osd_reg_array[index].osd_blk0_cfg_w0, 2, 28, 2);
7344 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
7345 osd_hw.osd_afbcd[index].enable == ENABLE)
7346 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7347 (hw_osd_reg_array[index].afbc_prefetch_cfg_s,
7348 2, 0, 2);
Googler4f18c0c2022-09-20 17:23:36 +08007349 } else {
Googler9398cc32022-12-02 17:21:52 +08007350 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7351 (hw_osd_reg_array[index].osd_blk0_cfg_w0, 0, 28, 2);
7352 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
7353 osd_hw.osd_afbcd[index].enable == ENABLE)
7354 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
7355 (hw_osd_reg_array[index].afbc_prefetch_cfg_s,
7356 0, 0, 2);
Googler4f18c0c2022-09-20 17:23:36 +08007357 }
7358 remove_from_update_list(index, DISP_OSD_REVERSE);
7359}
7360
7361static int get_viu2_src_format(void)
7362{
7363 return RGBA;
7364}
7365
7366static void osd_update_disp_osd_rotate(u32 index)
7367{
7368 u32 rotate_en = osd_hw.osd_rotate[index];
7369 u32 src_fmt;
7370 u32 x_start, x_end, y_start, y_end;
7371 u32 src_width, src_height;
7372 u32 rot_hsize, blk_vsize, rd_blk_hsize;
7373 u32 reg_fmt_buf_en, reg_fmt_444_mode, line5_mode;
7374 u32 y_reverse = 0, x_reverse = 0;
7375 u32 data32;
7376 enum color_index_e idx;
7377 struct dispdata_s src_data;
7378 const struct vinfo_s *vinfo = NULL;
7379 int out_y_crop_start, out_y_crop_end;
7380
7381 if (osd_hw.osd_meson_dev.cpu_id != __MESON_CPU_MAJOR_ID_G12B)
7382 return;
7383 src_fmt = get_viu2_src_format();
7384 src_data.x = 0;
7385 src_data.y = 0;
7386 src_data.w = osd_hw.fb_gem[index].xres;
7387 src_data.h = osd_hw.fb_gem[index].yres;
Googler4f18c0c2022-09-20 17:23:36 +08007388#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
7389 vinfo = get_current_vinfo2();
Googler9398cc32022-12-02 17:21:52 +08007390#endif
Googler4f18c0c2022-09-20 17:23:36 +08007391 if (!vinfo) {
7392 osd_log_err("current vinfo NULL\n");
7393 return;
7394 }
Googler4f18c0c2022-09-20 17:23:36 +08007395 out_y_crop_start = 0;
7396 out_y_crop_end = vinfo->height;
7397 src_width = src_data.w;
7398 src_height = src_data.h;
7399
7400 x_start = src_data.x;
7401 x_end = src_data.x + src_data.w - 1;
7402 y_start = src_data.y;
7403 y_end = src_data.y + src_data.h - 1;
7404 /* x/y start end can be crop axis */
7405 switch (src_fmt) {
7406 case YUV422:
7407 blk_vsize = 30;
7408 rd_blk_hsize = 32;
7409 reg_fmt_buf_en = 1;
7410 reg_fmt_444_mode = 0;
7411 line5_mode = 1;
7412 break;
7413 case RGB:
7414 blk_vsize = 20;
7415 rd_blk_hsize = 22;
7416 reg_fmt_buf_en = 0;
7417 reg_fmt_444_mode = 1;
7418 line5_mode = 0;
7419 break;
7420 case RGBA:
7421 blk_vsize = 15;
7422 rd_blk_hsize = 16;
7423 reg_fmt_buf_en = 0;
7424 reg_fmt_444_mode = 1;
7425 line5_mode = 0;
7426 break;
7427 }
7428 osd_reg_set_bits(VPP2_MISC, rotate_en, 16, 1);
7429 rotate_en = 0;
7430 osd_reg_set_bits(VPU_VIU_VENC_MUX_CTRL,
Googler9398cc32022-12-02 17:21:52 +08007431 rotate_en, 20, 1);
Googler4f18c0c2022-09-20 17:23:36 +08007432 idx = osd_hw.color_info[index]->color_index;
7433 data32 = (osd_hw.fb_gem[index].canvas_idx << 16) |
7434 (2 << 8) | (1 << 7) | (0 << 6) |
7435 (y_reverse << 5) |
7436 (x_reverse << 4) | src_fmt;
7437 osd_reg_set_bits(VIU2_RMIF_CTRL1, data32, 0, 32);
7438 osd_reg_set_bits(VIU2_RMIF_SCOPE_X,
Googler9398cc32022-12-02 17:21:52 +08007439 x_end << 16 | x_start, 0, 32);
Googler4f18c0c2022-09-20 17:23:36 +08007440 osd_reg_set_bits(VIU2_RMIF_SCOPE_Y,
Googler9398cc32022-12-02 17:21:52 +08007441 y_end << 16 | y_start, 0, 32);
Googler4f18c0c2022-09-20 17:23:36 +08007442
7443 rot_hsize = (src_height + blk_vsize - 1) / blk_vsize;
Googler9398cc32022-12-02 17:21:52 +08007444 osd_reg_set_bits(VIU2_ROT_BLK_SIZE,
7445 rd_blk_hsize | (blk_vsize << 8), 0, 32);
7446 osd_reg_set_bits(VIU2_ROT_LBUF_SIZE,
7447 rot_hsize * rd_blk_hsize |
7448 (rot_hsize << 16), 0, 32);
7449 osd_reg_set_bits(VIU2_ROT_FMT_CTRL,
7450 reg_fmt_buf_en |
7451 (line5_mode << 1) |
7452 (reg_fmt_444_mode << 2) |
7453 (180 << 8) | (0xe4 << 24), 0, 32);
Googler4f18c0c2022-09-20 17:23:36 +08007454 osd_reg_set_bits(VIU2_ROT_OUT_VCROP,
Googler9398cc32022-12-02 17:21:52 +08007455 out_y_crop_end |
7456 out_y_crop_start << 16, 0, 32);
7457 osd_reg_set_bits(VPP2_OFIFO_SIZE,
7458 src_height - 1, 20, 12);
Googler4f18c0c2022-09-20 17:23:36 +08007459 remove_from_update_list(index, DISP_OSD_ROTATE);
7460}
7461
7462static void osd_update_color_key(u32 index)
7463{
Googler9398cc32022-12-02 17:21:52 +08007464 u32 output_index = get_output_device_id(index);
7465
7466 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7467 (hw_osd_reg_array[index].osd_tcolor_ag0,
7468 osd_hw.color_key[index]);
Googler4f18c0c2022-09-20 17:23:36 +08007469 remove_from_update_list(index, OSD_COLOR_KEY);
7470}
7471
7472static void osd_update_color_key_enable(u32 index)
7473{
7474 u32 data32;
Googler9398cc32022-12-02 17:21:52 +08007475 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08007476
Googler9398cc32022-12-02 17:21:52 +08007477 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
7478 (hw_osd_reg_array[index].osd_blk0_cfg_w0);
Googler4f18c0c2022-09-20 17:23:36 +08007479 data32 &= ~(1 << 6);
7480 data32 |= (osd_hw.color_key_enable[index] << 6);
Googler9398cc32022-12-02 17:21:52 +08007481 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7482 (hw_osd_reg_array[index].osd_blk0_cfg_w0,
7483 data32);
Googler4f18c0c2022-09-20 17:23:36 +08007484 /*
7485 * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK1_CFG_W0, data32);
7486 * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK2_CFG_W0, data32);
7487 * VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK3_CFG_W0, data32);
7488 */
7489 remove_from_update_list(index, OSD_COLOR_KEY_ENABLE);
7490}
7491
7492static void osd_update_gbl_alpha(u32 index)
7493{
7494 u32 data32;
Googler9398cc32022-12-02 17:21:52 +08007495 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08007496
Googler9398cc32022-12-02 17:21:52 +08007497 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
7498 (hw_osd_reg_array[index].osd_ctrl_stat);
Googler4f18c0c2022-09-20 17:23:36 +08007499 data32 &= ~(0x1ff << 12);
7500 data32 |= osd_hw.gbl_alpha[index] << 12;
Googler9398cc32022-12-02 17:21:52 +08007501 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
7502 (hw_osd_reg_array[index].osd_ctrl_stat,
7503 data32);
Googler4f18c0c2022-09-20 17:23:36 +08007504 remove_from_update_list(index, OSD_GBL_ALPHA);
7505}
7506
7507static void osd_update_order(u32 index)
7508{
7509 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
7510 switch (osd_hw.order[index]) {
7511 case OSD_ORDER_01:
7512 if (!osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +08007513 osd_reg_clr_mask(VPP_MISC,
7514 VPP_POST_FG_OSD2 |
7515 VPP_PRE_FG_OSD2);
Googler4f18c0c2022-09-20 17:23:36 +08007516 osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2);
7517 break;
7518 case OSD_ORDER_10:
7519 /* OSD2 is top */
7520 if (!osd_hw.hw_rdma_en)
7521 osd_reg_set_mask(VPP_MISC,
Googler9398cc32022-12-02 17:21:52 +08007522 VPP_POST_FG_OSD2 |
7523 VPP_PRE_FG_OSD2);
Googler4f18c0c2022-09-20 17:23:36 +08007524 osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2);
7525 break;
7526 default:
7527 break;
7528 }
7529 notify_to_amvideo();
7530 }
7531
7532 remove_from_update_list(index, OSD_CHANGE_ORDER);
7533}
7534
Googler4f18c0c2022-09-20 17:23:36 +08007535static void osd1_2x_scale_update_geometry(void)
7536{
7537 u32 data32;
7538
7539 data32 = (osd_hw.scaledata[OSD1].x_start & 0x1fff) |
7540 (osd_hw.scaledata[OSD1].x_end & 0x1fff) << 16;
7541 VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W1, data32);
7542
7543 if (osd_hw.osd_afbcd[OSD1].enable) {
7544 data32 = (osd_hw.scaledata[OSD1].x_end & 0x1fff) |
7545 (osd_hw.scaledata[OSD1].x_start & 0x1fff) << 16;
7546 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_HSCOPE, data32);
7547 data32 = (osd_hw.scaledata[OSD1].y_end & 0x1fff) |
7548 (osd_hw.scaledata[OSD1].y_start & 0x1fff) << 16;
7549 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_VSCOPE, data32);
7550 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_HDR_PTR,
Googler9398cc32022-12-02 17:21:52 +08007551 osd_hw.osd_afbcd[OSD1].phy_addr >> 4);
Googler4f18c0c2022-09-20 17:23:36 +08007552 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_FRAME_PTR,
Googler9398cc32022-12-02 17:21:52 +08007553 osd_hw.osd_afbcd[OSD1].phy_addr >> 4);
Googler4f18c0c2022-09-20 17:23:36 +08007554 data32 = (0xe4 << 24) |
7555 (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff);
Googler9398cc32022-12-02 17:21:52 +08007556 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_CHROMA_PTR,
7557 data32);
Googler4f18c0c2022-09-20 17:23:36 +08007558 }
7559
7560 data32 = ((osd_hw.scaledata[OSD1].y_start
7561 + osd_hw.pandata[OSD1].y_start) & 0x1fff)
7562 | ((osd_hw.scaledata[OSD1].y_end
7563 + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +08007564 VSYNCOSD_WR_MPEG_REG
7565 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +08007566 /* adjust display x-axis */
7567 if (osd_hw.scale[OSD1].h_enable) {
7568 data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff)
7569 | ((osd_hw.dispdata[OSD1].x_start
7570 + (osd_hw.scaledata[OSD1].x_end
7571 - osd_hw.scaledata[OSD1].x_start) * 2 + 1)
7572 & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +08007573 VSYNCOSD_WR_MPEG_REG
7574 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w3, data32);
Googler4f18c0c2022-09-20 17:23:36 +08007575 if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) {
7576 data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff)
7577 | (((((osd_hw.dispdata[OSD1].y_start
7578 + (osd_hw.scaledata[OSD1].y_end
7579 - osd_hw.scaledata[OSD1].y_start) * 2)
7580 + 1) >> 1) - 1) & 0xfff) << 16;
7581 } else {
7582 data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff)
7583 | (((osd_hw.dispdata[OSD1].y_start
7584 + (osd_hw.scaledata[OSD1].y_end
7585 - osd_hw.scaledata[OSD1].y_start) * 2))
7586 & 0xfff) << 16;
7587 }
Googler9398cc32022-12-02 17:21:52 +08007588 VSYNCOSD_WR_MPEG_REG
7589 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w4, data32);
Googler4f18c0c2022-09-20 17:23:36 +08007590 }
7591 /* adjust display y-axis */
7592 if (osd_hw.scale[OSD1].v_enable) {
7593 data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff)
7594 | ((osd_hw.dispdata[OSD1].x_start
7595 + (osd_hw.scaledata[OSD1].x_end
7596 - osd_hw.scaledata[OSD1].x_start) * 2 + 1)
7597 & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +08007598 VSYNCOSD_WR_MPEG_REG
7599 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w3, data32);
Googler4f18c0c2022-09-20 17:23:36 +08007600 if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE) {
7601 data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff)
7602 | (((((osd_hw.dispdata[OSD1].y_start
7603 + (osd_hw.scaledata[OSD1].y_end
7604 - osd_hw.scaledata[OSD1].y_start) * 2)
7605 + 1) >> 1) - 1) & 0xfff) << 16;
7606 } else {
7607 data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff)
7608 | (((osd_hw.dispdata[OSD1].y_start
7609 + (osd_hw.scaledata[OSD1].y_end
7610 - osd_hw.scaledata[OSD1].y_start) * 2))
7611 & 0xfff) << 16;
7612 }
Googler9398cc32022-12-02 17:21:52 +08007613 VSYNCOSD_WR_MPEG_REG
7614 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w4, data32);
Googler4f18c0c2022-09-20 17:23:36 +08007615 }
7616}
7617
7618static u32 _set_bits(u32 data32, u32 bits, u32 value)
7619{
7620 data32 &= ~(1 << bits);
7621 data32 |= (value << bits);
7622 return data32;
7623}
7624
7625void insert_sort(u32 *array, int length)
7626{
7627 int i = 0, j = 0;
7628 u32 temp;
7629
7630 /* decrease */
7631 for (j = 0; j < length; j++) {
Googler9398cc32022-12-02 17:21:52 +08007632 for (i = j + 1; i < length; i++) {
Googler4f18c0c2022-09-20 17:23:36 +08007633 if (array[j] < array[i]) {
7634 temp = array[j];
7635 array[j] = array[i];
7636 array[i] = temp;
7637 }
7638 }
7639 }
7640}
7641
Googler9398cc32022-12-02 17:21:52 +08007642static int get_available_layers(u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +08007643{
7644 int i;
7645 int available_layer = 0;
7646
Googler9398cc32022-12-02 17:21:52 +08007647 for (i = 0 ; i < osd_hw.osd_meson_dev.osd_count; i++) {
7648 if (osd_hw.enable[i] && validate_osd(i, output_index))
Googler4f18c0c2022-09-20 17:23:36 +08007649 available_layer++;
7650 }
7651 return available_layer;
7652}
7653
Googler9398cc32022-12-02 17:21:52 +08007654static u32 blend_din_to_osd(u32 blend_din_index,
7655 struct hw_osd_blending_s *blending)
Googler4f18c0c2022-09-20 17:23:36 +08007656{
7657 u32 osd_index = 0;
7658
Googler9398cc32022-12-02 17:21:52 +08007659 if (!blending)
7660 return 0;
7661
Googler4f18c0c2022-09-20 17:23:36 +08007662 osd_index =
7663 blending->osd_to_bdin_table[blend_din_index];
Googler9398cc32022-12-02 17:21:52 +08007664 if (!validate_osd(osd_index, VIU1))
Googler4f18c0c2022-09-20 17:23:36 +08007665 return OSD_MAX;
7666 else
7667 return osd_index;
7668}
7669
Googler9398cc32022-12-02 17:21:52 +08007670static u32 get_layer_to_osd(struct hw_osd_blending_s *blending, u32 layer)
Googler4f18c0c2022-09-20 17:23:36 +08007671{
Googler9398cc32022-12-02 17:21:52 +08007672 int i = 0;
7673 u32 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
Googler4f18c0c2022-09-20 17:23:36 +08007674
Googler9398cc32022-12-02 17:21:52 +08007675 for (i = 0; i < osd_count; i++) {
7676 if (blending->reorder[i] == layer)
7677 return i;
7678 }
7679 return 0;
Googler4f18c0c2022-09-20 17:23:36 +08007680}
7681
7682static void exchange_din0_din2(struct hw_osd_blending_s *blending)
7683{
7684 int temp1 = 0, temp2 = 0;
7685
7686 osd_log_dbg(MODULE_BLEND, "need exchange osd din0 and din2 order\n");
7687 temp1 = blending->din_reoder_sel & 0x000f;
7688 temp2 = blending->din_reoder_sel & 0x0f00;
7689 blending->din_reoder_sel &= ~0x0f0f;
7690 blending->din_reoder_sel |= temp1 << 8;
7691 blending->din_reoder_sel |= temp2 >> 8;
7692 temp1 = blending->osd_to_bdin_table[0];
7693 temp2 = blending->osd_to_bdin_table[2];
7694 blending->osd_to_bdin_table[2] = temp1;
7695 blending->osd_to_bdin_table[0] = temp2;
7696 osd_log_dbg(MODULE_BLEND, "din_reoder_sel%x\n",
Googler9398cc32022-12-02 17:21:52 +08007697 blending->din_reoder_sel);
Googler4f18c0c2022-09-20 17:23:36 +08007698}
7699
7700static void exchange_din2_din3(struct hw_osd_blending_s *blending)
7701{
7702 int temp1 = 0, temp2 = 0;
7703
7704 osd_log_dbg(MODULE_BLEND, "need exchange osd din2 and din3 order\n");
7705 temp1 = blending->din_reoder_sel & 0x0f00;
7706 temp2 = blending->din_reoder_sel & 0xf000;
7707 blending->din_reoder_sel &= ~0xff00;
7708 blending->din_reoder_sel |= temp1 << 4;
7709 blending->din_reoder_sel |= temp2 >> 4;
7710 temp1 = blending->osd_to_bdin_table[2];
7711 temp2 = blending->osd_to_bdin_table[3];
7712 blending->osd_to_bdin_table[3] = temp1;
7713 blending->osd_to_bdin_table[2] = temp2;
7714 osd_log_dbg(MODULE_BLEND, "din_reoder_sel%x\n",
Googler9398cc32022-12-02 17:21:52 +08007715 blending->din_reoder_sel);
Googler4f18c0c2022-09-20 17:23:36 +08007716}
7717
7718static void exchange_vpp_order(struct hw_osd_blending_s *blending)
7719{
Googler9398cc32022-12-02 17:21:52 +08007720 blending->b_exchange_blend_in = 1;
Googler4f18c0c2022-09-20 17:23:36 +08007721 osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n");
7722}
7723
7724static void generate_blend_din_table(struct hw_osd_blending_s *blending)
7725{
7726 int i = 0;
7727 int temp1 = 0, temp2 = 0;
Googler9398cc32022-12-02 17:21:52 +08007728 int osd_count = osd_hw.osd_meson_dev.osd_count;
Googler4f18c0c2022-09-20 17:23:36 +08007729
7730 /* reorder[i] = osd[i]'s display layer */
7731 for (i = 0; i < OSD_BLEND_LAYERS; i++)
7732 blending->osd_to_bdin_table[i] = -1;
7733 blending->din_reoder_sel = 0;
7734 switch (blending->layer_cnt) {
7735 case 0:
7736 break;
7737 case 1:
7738 for (i = 0; i < osd_count; i++) {
7739 if (blending->reorder[i] != LAYER_UNSUPPORT) {
7740 /* blend_din1 */
7741 blending->din_reoder_sel |= (i + 1) << 0;
7742 /* blend_din1 -- osdx */
7743 blending->osd_to_bdin_table[0] = i;
7744 break;
7745 }
7746 }
7747 break;
7748 case 2:
7749 {
7750 int temp_index[2] = {0};
7751 int j = 0;
7752
7753 for (i = 0; i < osd_count; i++) {
7754 if (blending->reorder[i] != LAYER_UNSUPPORT) {
7755 /* save the osd index */
7756 temp_index[j] = i;
7757 j++;
7758 }
7759 }
7760 osd_log_dbg(MODULE_BLEND, "blend_din4==%d\n",
Googler9398cc32022-12-02 17:21:52 +08007761 blending->reorder[temp_index[0]]);
Googler4f18c0c2022-09-20 17:23:36 +08007762 osd_log_dbg(MODULE_BLEND, "blend_din1==%d\n",
Googler9398cc32022-12-02 17:21:52 +08007763 blending->reorder[temp_index[1]]);
Googler4f18c0c2022-09-20 17:23:36 +08007764 /* mode A_C */
7765 if (blending->osd_blend_mode == OSD_BLEND_A_C) {
7766 /* blend_din1 */
7767 blending->din_reoder_sel |= (temp_index[0] + 1) << 0;
7768 /* blend_din1 -- osdx */
7769 blending->osd_to_bdin_table[0] = temp_index[0];
7770 /* blend_din3 */
7771 blending->din_reoder_sel |= (temp_index[1] + 1) << 12;
7772 /* blend_din3 -- osdx */
7773 blending->osd_to_bdin_table[3] = temp_index[1];
7774 /* exchane vpp osd blend in order */
7775 if (blending->reorder[temp_index[0]] <
7776 blending->reorder[temp_index[1]]) {
Googler9398cc32022-12-02 17:21:52 +08007777 blending->b_exchange_blend_in = 1;
Googler4f18c0c2022-09-20 17:23:36 +08007778 osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n");
7779 }
7780 } else {
7781 if (blending->reorder[temp_index[0]] <
7782 blending->reorder[temp_index[1]]) {
7783 /* blend_din4 */
7784 blending->din_reoder_sel |=
7785 (temp_index[0] + 1) << 12;
7786 /* blend_din3 -- osdx */
7787 blending->osd_to_bdin_table[3] = temp_index[0];
7788 /* blend_din1 */
7789 blending->din_reoder_sel |=
7790 (temp_index[1] + 1) << 0;
7791 /* blend_din1 -- osdx */
7792 blending->osd_to_bdin_table[0] = temp_index[1];
Googler9398cc32022-12-02 17:21:52 +08007793 blending->b_exchange_din = 1;
Googler4f18c0c2022-09-20 17:23:36 +08007794 osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n");
7795 } else {
7796 /* blend_din1 */
7797 blending->din_reoder_sel |=
7798 (temp_index[0] + 1) << 0;
7799 /* blend_din1 -- osdx */
7800 blending->osd_to_bdin_table[0] = temp_index[0];
7801 /* blend_din3 */
7802 blending->din_reoder_sel |=
7803 (temp_index[1] + 1) << 12;
7804 /* blend_din3 -- osdx */
7805 blending->osd_to_bdin_table[3] = temp_index[1];
7806 }
7807 }
7808 break;
7809 }
7810 case 3:
7811 /* blend_din1 is bottom, blend_din4 is top layer */
Googler9398cc32022-12-02 17:21:52 +08007812 osd_log_dbg(MODULE_BLEND, "reorder:%d,%d,%d,%d\n",
7813 blending->reorder[OSD1],
7814 blending->reorder[OSD2],
7815 blending->reorder[OSD3],
7816 blending->reorder[OSD4]);
Googler4f18c0c2022-09-20 17:23:36 +08007817 if (blending->osd_blend_mode == OSD_BLEND_AB_C) {
7818 /* suppose osd0 used blend_din1,
7819 * osd1 used din2, osd3 used din4
7820 */
7821 /* blend_din1 */
7822 blending->din_reoder_sel |= 1 << 0;
7823 /* blend_din1 -- osd1 */
7824 blending->osd_to_bdin_table[0] = OSD1;
7825 /* blend_din3 */
7826 blending->din_reoder_sel |= (OSD2 + 1) << 8;
7827 /* blend_din3 -- osd2 */
7828 blending->osd_to_bdin_table[2] = OSD2;
7829 /* blend_din4 */
7830 blending->din_reoder_sel |= (OSD3 + 1) << 12;
7831 /* blend_din4 -- osd3 */
7832 blending->osd_to_bdin_table[3] = OSD3;
Googler9398cc32022-12-02 17:21:52 +08007833 if (blending->reorder[OSD1] == LAYER_3 &&
7834 blending->reorder[OSD2] == LAYER_2 &&
7835 blending->reorder[OSD3] == LAYER_1) {
Googler4f18c0c2022-09-20 17:23:36 +08007836 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08007837 "use default order\n");
7838 } else if ((blending->reorder[OSD1] == LAYER_2) &&
7839 (blending->reorder[OSD2] == LAYER_3) &&
7840 (blending->reorder[OSD3] == LAYER_1)) {
Googler4f18c0c2022-09-20 17:23:36 +08007841 exchange_din0_din2(blending);
Googler9398cc32022-12-02 17:21:52 +08007842 } else if ((blending->reorder[OSD1] == LAYER_2) &&
7843 (blending->reorder[OSD2] == LAYER_1) &&
7844 (blending->reorder[OSD3] == LAYER_3)) {
Googler4f18c0c2022-09-20 17:23:36 +08007845 exchange_vpp_order(blending);
Googler9398cc32022-12-02 17:21:52 +08007846 } else if ((blending->reorder[OSD1] == LAYER_1) &&
7847 (blending->reorder[OSD2] == LAYER_2) &&
7848 (blending->reorder[OSD3] == LAYER_3)) {
Googler4f18c0c2022-09-20 17:23:36 +08007849 exchange_din0_din2(blending);
7850 exchange_vpp_order(blending);
Googler9398cc32022-12-02 17:21:52 +08007851 } else if ((blending->reorder[OSD1] == LAYER_3) &&
7852 (blending->reorder[OSD2] == LAYER_1) &&
7853 (blending->reorder[OSD3] == LAYER_2)) {
Googler4f18c0c2022-09-20 17:23:36 +08007854 exchange_din2_din3(blending);
Googler9398cc32022-12-02 17:21:52 +08007855 } else if (blending->reorder[OSD1] == LAYER_1 &&
7856 blending->reorder[OSD2] == LAYER_3 &&
7857 blending->reorder[OSD3] == LAYER_2) {
Googler4f18c0c2022-09-20 17:23:36 +08007858 exchange_din2_din3(blending);
7859 exchange_din0_din2(blending);
7860 exchange_vpp_order(blending);
7861 }
7862 } else if (blending->osd_blend_mode == OSD_BLEND_ABC) {
7863 u32 osd_index = 0;
7864
Googler9398cc32022-12-02 17:21:52 +08007865 osd_index = get_layer_to_osd(blending, LAYER_3);
Googler4f18c0c2022-09-20 17:23:36 +08007866 /* blend_din1 is max_order*/
7867 blending->din_reoder_sel |= (osd_index + 1) << 0;
7868 blending->osd_to_bdin_table[0] = osd_index;
7869
Googler9398cc32022-12-02 17:21:52 +08007870 osd_index = get_layer_to_osd(blending, LAYER_1);
Googler4f18c0c2022-09-20 17:23:36 +08007871 /* blend_din4 is min_order*/
7872 blending->din_reoder_sel |= (osd_index + 1) << 12;
7873 blending->osd_to_bdin_table[3] = osd_index;
7874
Googler9398cc32022-12-02 17:21:52 +08007875 osd_index = get_layer_to_osd(blending, LAYER_2);
Googler4f18c0c2022-09-20 17:23:36 +08007876 /* blend_din3 is middle_order*/
7877 blending->din_reoder_sel |= (osd_index + 1) << 8;
7878 blending->osd_to_bdin_table[2] = osd_index;
7879 }
7880 break;
Googler9398cc32022-12-02 17:21:52 +08007881 case 4:
7882 /* blend_din1 is bottom, blend_din4 is top layer */
7883 osd_log_dbg2(MODULE_BLEND, "reorder:%d,%d,%d,%d\n",
7884 blending->reorder[OSD1],
7885 blending->reorder[OSD2],
7886 blending->reorder[OSD3],
7887 blending->reorder[OSD4]);
7888 if (blending->osd_blend_mode == OSD_BLEND_AB_CD) {
7889 u32 osd_index = 0;
7890
7891 osd_index = get_layer_to_osd(blending, LAYER_1);
7892 /* blend_din4 is LAYER_1 */
7893 blending->din_reoder_sel |= (osd_index + 1) << 12;
7894 blending->osd_to_bdin_table[3] = osd_index;
7895
7896 osd_index = get_layer_to_osd(blending, LAYER_2);
7897 /* blend_din3 is LAYER_2*/
7898 blending->din_reoder_sel |= (osd_index + 1) << 8;
7899 blending->osd_to_bdin_table[2] = osd_index;
7900
7901 osd_index = get_layer_to_osd(blending, LAYER_3);
7902 /* blend_din2 is LAYER_3*/
7903 blending->din_reoder_sel |= (osd_index + 1) << 4;
7904 blending->osd_to_bdin_table[1] = osd_index;
7905
7906 /* blend_din1 is LAYER_4*/
7907 osd_index = get_layer_to_osd(blending, LAYER_4);
7908 blending->din_reoder_sel |= (osd_index + 1) << 0;
7909 blending->osd_to_bdin_table[0] = osd_index;
7910
7911 } else if (blending->osd_blend_mode == OSD_BLEND_ABCD) {
7912 u32 osd_index = 0;
7913
7914 osd_index = get_layer_to_osd(blending, LAYER_1);
7915 /* blend_din4 is LAYER_1 */
7916 blending->din_reoder_sel |= (osd_index + 1) << 12;
7917 blending->osd_to_bdin_table[3] = osd_index;
7918
7919 osd_index = get_layer_to_osd(blending, LAYER_2);
7920 /* blend_din3 is LAYER_2*/
7921 blending->din_reoder_sel |= (osd_index + 1) << 8;
7922 blending->osd_to_bdin_table[2] = osd_index;
7923
7924 osd_index = get_layer_to_osd(blending, LAYER_3);
7925 /* blend_din2 is LAYER_3*/
7926 blending->din_reoder_sel |= (osd_index + 1) << 4;
7927 blending->osd_to_bdin_table[1] = osd_index;
7928
7929 /* blend_din1 is LAYER_4*/
7930 osd_index = get_layer_to_osd(blending, LAYER_4);
7931 blending->din_reoder_sel |= (osd_index + 1) << 0;
7932 blending->osd_to_bdin_table[0] = osd_index;
7933 }
7934 break;
Googler4f18c0c2022-09-20 17:23:36 +08007935 }
7936
7937 /* workaround for shift issue */
7938 /* not enable layers used osd4 */
7939 temp2 = 0;
7940 for (i = 0; i < OSD_BLEND_LAYERS; i++) {
Googler9398cc32022-12-02 17:21:52 +08007941 temp1 = (blending->din_reoder_sel >> (i * 4)) & 0xf;
Googler4f18c0c2022-09-20 17:23:36 +08007942 if (!(temp1 & 0x0f))
Googler9398cc32022-12-02 17:21:52 +08007943 temp2 |= (0x04 << (i * 4));
Googler4f18c0c2022-09-20 17:23:36 +08007944 }
7945 blending->din_reoder_sel |= temp2;
7946 osd_log_dbg(MODULE_BLEND, "osd_to_bdin_table[i]=[%x,%x,%x,%x]\n",
Googler9398cc32022-12-02 17:21:52 +08007947 blending->osd_to_bdin_table[0],
7948 blending->osd_to_bdin_table[1],
7949 blending->osd_to_bdin_table[2],
7950 blending->osd_to_bdin_table[3]);
7951 blending->osd_blend_reg.din_reoder_sel =
Googler4f18c0c2022-09-20 17:23:36 +08007952 blending->din_reoder_sel;
7953}
7954
Googler9726be62022-12-14 05:53:31 +00007955#ifdef FREESCAL_CHECK
Googler4f18c0c2022-09-20 17:23:36 +08007956static bool is_freescale_para_changed(u32 index)
7957{
7958 static int first[HW_OSD_COUNT - 1] = {1};
7959 bool freescale_update = false;
7960
Googler9398cc32022-12-02 17:21:52 +08007961 if (memcmp(&osd_hw.free_src_data[index],
7962 &osd_hw.free_src_data_backup[index],
7963 sizeof(struct pandata_s)) != 0 ||
7964 memcmp(&osd_hw.free_dst_data[index],
7965 &osd_hw.free_dst_data_backup[index],
7966 sizeof(struct pandata_s)) != 0) {
7967 memcpy(&osd_hw.free_src_data_backup[index],
7968 &osd_hw.free_src_data[index],
7969 sizeof(struct pandata_s));
7970 memcpy(&osd_hw.free_dst_data_backup[index],
7971 &osd_hw.free_dst_data[index],
7972 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +08007973 freescale_update = true;
7974 }
7975 if (first[index])
7976 freescale_update = true;
7977 first[index] = 0;
7978 return freescale_update;
7979}
Googler9726be62022-12-14 05:53:31 +00007980#endif
Googler4f18c0c2022-09-20 17:23:36 +08007981
7982static int osd_setting_blending_scope(u32 index)
7983{
7984 u32 bld_osd_h_start, bld_osd_h_end;
7985 u32 bld_osd_v_start, bld_osd_v_end;
7986 u32 reg_offset = 2;
Googler9398cc32022-12-02 17:21:52 +08007987 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08007988
7989 if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
7990 osd_log_err("error osd index=%d\n", index);
7991 return -1;
7992 }
Googler9726be62022-12-14 05:53:31 +00007993
7994 if (index == OSD1) {
7995 bld_osd_h_start =
7996 osd_hw.free_src_data[index].x_start;
7997 bld_osd_h_end =
7998 osd_hw.free_src_data[index].x_end;
7999 bld_osd_v_start =
8000 osd_hw.free_src_data[index].y_start;
8001 bld_osd_v_end =
8002 osd_hw.free_src_data[index].y_end;
8003 } else {
8004 bld_osd_h_start =
8005 osd_hw.dst_data[index].x;
8006 bld_osd_h_end =
8007 osd_hw.dst_data[index].x +
8008 osd_hw.dst_data[index].w - 1;
8009 bld_osd_v_start =
8010 osd_hw.dst_data[index].y;
8011 bld_osd_v_end =
8012 osd_hw.dst_data[index].y +
8013 osd_hw.dst_data[index].h - 1;
8014 }
Googler4f18c0c2022-09-20 17:23:36 +08008015
8016 osd_log_dbg(MODULE_BLEND, "osd%d_hw.dst_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +08008017 index,
8018 osd_hw.dst_data[index].x,
8019 osd_hw.dst_data[index].y,
8020 osd_hw.dst_data[index].w,
8021 osd_hw.dst_data[index].h);
Googler4f18c0c2022-09-20 17:23:36 +08008022 osd_log_dbg(MODULE_BLEND, "h,v axis:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +08008023 bld_osd_h_start,
8024 bld_osd_h_end,
8025 bld_osd_v_start,
8026 bld_osd_v_end);
Googler4f18c0c2022-09-20 17:23:36 +08008027
8028 /* it is setting for osdx */
Googler9398cc32022-12-02 17:21:52 +08008029 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
8030 (VIU_OSD_BLEND_DIN0_SCOPE_H +
8031 reg_offset * index,
Googler4f18c0c2022-09-20 17:23:36 +08008032 bld_osd_h_end << 16 |
8033 bld_osd_h_start);
Googler9398cc32022-12-02 17:21:52 +08008034 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
8035 (VIU_OSD_BLEND_DIN0_SCOPE_V +
8036 reg_offset * index,
Googler4f18c0c2022-09-20 17:23:36 +08008037 bld_osd_v_end << 16 |
8038 bld_osd_v_start);
8039 return 0;
8040}
8041
8042static int vpp_blend_setting_default(u32 index)
8043{
8044 u32 osd1_dst_h = 0, osd1_dst_v = 0;
8045 u32 osd1_h_start = 0, osd1_h_end = 0;
8046 u32 osd1_v_start = 0, osd1_v_end = 0;
Googler9398cc32022-12-02 17:21:52 +08008047 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +08008048
Googler9398cc32022-12-02 17:21:52 +08008049 osd_log_dbg(MODULE_BASE, "%s\n", __func__);
Googler4f18c0c2022-09-20 17:23:36 +08008050
8051 if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
8052 osd_log_err("error osd index=%d\n", index);
8053 return -1;
8054 }
8055 if (osd_hw.free_scale_enable[index]) {
8056 osd1_dst_h = osd_hw.free_dst_data[index].x_end
8057 - osd_hw.free_dst_data[index].x_start + 1;
8058 osd1_dst_v = osd_hw.free_dst_data[index].y_end
8059 - osd_hw.free_dst_data[index].y_start + 1;
8060 osd1_h_start = osd_hw.free_dst_data[index].x_start;
8061 osd1_h_end = osd_hw.free_dst_data[index].x_end;
8062 osd1_v_start = osd_hw.free_dst_data[index].y_start;
8063 osd1_v_end = osd_hw.free_dst_data[index].y_end;
8064 } else {
8065 osd1_dst_h = osd_hw.dispdata[index].x_end
8066 - osd_hw.dispdata[index].x_start + 1;
8067 osd1_dst_v = osd_hw.dispdata[index].y_end
8068 - osd_hw.dispdata[index].y_start + 1;
8069 osd1_h_start = osd_hw.dispdata[index].x_start;
8070 osd1_h_end = osd_hw.dispdata[index].x_end;
8071 osd1_v_start = osd_hw.dispdata[index].y_start;
8072 osd1_v_end = osd_hw.dispdata[index].y_end;
8073 }
8074
8075 /* setting blend scope */
Googler9398cc32022-12-02 17:21:52 +08008076 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
8077 (VPP_OSD1_BLD_H_SCOPE,
Googler9726be62022-12-14 05:53:31 +00008078 osd1_h_start << 16 | osd1_h_end);
Googler9398cc32022-12-02 17:21:52 +08008079 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
8080 (VPP_OSD1_BLD_V_SCOPE,
Googler9726be62022-12-14 05:53:31 +00008081 osd1_v_start << 16 | osd1_v_end);
Googler4f18c0c2022-09-20 17:23:36 +08008082
8083 return 0;
8084}
8085
Googler4f18c0c2022-09-20 17:23:36 +08008086static u32 order[HW_OSD_COUNT];
8087static struct hw_osd_blending_s osd_blending;
8088
Googler9398cc32022-12-02 17:21:52 +08008089static void set_blend_order(struct hw_osd_blending_s *blending, u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +08008090{
8091 u32 org_order[HW_OSD_COUNT];
8092 int i = 0, j = 0;
Googler9398cc32022-12-02 17:21:52 +08008093 u32 osd_count = osd_hw.osd_meson_dev.osd_count;
Googler4f18c0c2022-09-20 17:23:36 +08008094
8095 if (!blending)
8096 return;
Googler9398cc32022-12-02 17:21:52 +08008097
8098 osd_log_dbg2(MODULE_BLEND, "user space zorder: %d %d %d %d\n",
8099 osd_hw.order[0],
8100 osd_hw.order[1],
8101 osd_hw.order[2],
8102 osd_hw.order[3]);
8103
Googler4f18c0c2022-09-20 17:23:36 +08008104 /* number largest is top layer */
8105 for (i = 0; i < osd_count; i++) {
8106 org_order[i] = osd_hw.order[i];
Googler9398cc32022-12-02 17:21:52 +08008107 if (!osd_hw.enable[i] || !validate_osd(i, output_index))
Googler4f18c0c2022-09-20 17:23:36 +08008108 org_order[i] = 0;
8109 order[i] = org_order[i];
8110 }
Googler9398cc32022-12-02 17:21:52 +08008111 osd_log_dbg2(MODULE_BLEND, "org zorder: %d %d %d %d\n",
8112 order[0], order[1], order[2], order[3]);
8113
Googler4f18c0c2022-09-20 17:23:36 +08008114 insert_sort(order, osd_count);
8115 //check_order_continuous(order);
Googler9398cc32022-12-02 17:21:52 +08008116 osd_log_dbg2(MODULE_BLEND, "after sort:zorder:%d,%d,%d,%d\n",
8117 order[0], order[1], order[2], order[3]);
Googler4f18c0c2022-09-20 17:23:36 +08008118
8119 /* reorder[i] = osd[i]'s display layer */
8120 for (i = 0; i < osd_count; i++) {
8121 for (j = 0; j < osd_count; j++) {
8122 if (order[i] == org_order[j]) {
Googler9398cc32022-12-02 17:21:52 +08008123 if (osd_hw.enable[j] &&
8124 validate_osd(j, output_index))
Googler4f18c0c2022-09-20 17:23:36 +08008125 blending->reorder[j] = LAYER_1 + i;
8126 else
8127 blending->reorder[j] =
8128 LAYER_UNSUPPORT;
8129 }
8130 }
8131 }
Googler9398cc32022-12-02 17:21:52 +08008132 osd_log_dbg2(MODULE_BLEND, "after reorder:zorder:%d,%d,%d,%d\n",
8133 blending->reorder[0],
8134 blending->reorder[1],
8135 blending->reorder[2],
8136 blending->reorder[3]);
Googler4f18c0c2022-09-20 17:23:36 +08008137}
8138
8139static void set_blend_din(struct hw_osd_blending_s *blending)
8140{
8141 int i = 0, osd_index;
8142 /* workaround for shift issue */
8143 /* blend_din_en must equal 5 */
8144 u32 blend_din_en = 0x5;
Googler9398cc32022-12-02 17:21:52 +08008145 u32 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
Googler4f18c0c2022-09-20 17:23:36 +08008146
8147 if (!blending)
8148 return;
Googler9398cc32022-12-02 17:21:52 +08008149 if (osd_dev_hw.t7_display)
8150 blend_din_en = 0x0;
Googler4f18c0c2022-09-20 17:23:36 +08008151 for (i = 0; i < OSD_BLEND_LAYERS; i++) {
8152 /* find osd index */
8153 osd_index = blend_din_to_osd(i, blending);
Googler9398cc32022-12-02 17:21:52 +08008154 if (osd_index >= OSD1 && osd_index < osd_count) {
Googler4f18c0c2022-09-20 17:23:36 +08008155 /* depend on osd enable */
Googler9398cc32022-12-02 17:21:52 +08008156 blend_din_en = _set_bits(blend_din_en,
8157 i,
8158 osd_hw.enable[osd_index]);
Googler4f18c0c2022-09-20 17:23:36 +08008159 }
8160 }
Googler9398cc32022-12-02 17:21:52 +08008161 osd_log_dbg2(MODULE_BLEND, "%s: blend_din_en=%x\n",
8162 __func__, blend_din_en);
8163
8164 blending->osd_blend_reg.blend_din_en = blend_din_en;
Googler4f18c0c2022-09-20 17:23:36 +08008165}
8166
8167static void set_blend_mode(struct hw_osd_blending_s *blending)
8168{
8169 u8 osd_blend_mode = OSD_BLEND_NONE;
8170
8171 if (!blending)
8172 return;
8173 switch (blending->layer_cnt) {
8174 case 0:
8175 osd_blend_mode = OSD_BLEND_NONE;
8176 break;
8177 case 1:
8178 /* select blend_din1 always */
8179 osd_blend_mode = OSD_BLEND_A;
8180 break;
8181 case 2:
8182 /* select blend_din1, blend_din4 always */
8183 if (osd_hw.hdr_used)
8184 osd_blend_mode = OSD_BLEND_AC;
8185 else
8186 osd_blend_mode = OSD_BLEND_A_C;
8187 break;
8188 case 3:
8189 /* select blend_din1, blend_din3 blend_din4 always */
8190 if (osd_hw.hdr_used)
8191 osd_blend_mode = OSD_BLEND_ABC;
8192 else
8193 osd_blend_mode = OSD_BLEND_AB_C;
8194 break;
Googler9398cc32022-12-02 17:21:52 +08008195 case 4:
8196 if (osd_hw.hdr_used)
8197 osd_blend_mode = OSD_BLEND_ABCD;
8198 else
8199 osd_blend_mode = OSD_BLEND_AB_CD;
8200 break;
Googler4f18c0c2022-09-20 17:23:36 +08008201 }
8202 blending->osd_blend_mode = osd_blend_mode;
8203 osd_log_dbg2(MODULE_BLEND, "osd_blend_mode=%d\n",
Googler9398cc32022-12-02 17:21:52 +08008204 blending->osd_blend_mode);
Googler4f18c0c2022-09-20 17:23:36 +08008205}
8206
8207static void calc_max_output(struct hw_osd_blending_s *blending)
8208{
8209 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +08008210 int input1_end_x, input1_end_y;
8211 int input2_end_x, input2_end_y;
Googler4f18c0c2022-09-20 17:23:36 +08008212 u32 output_end_x, output_end_y;
8213
8214 if (!blending)
8215 return;
Googler9398cc32022-12-02 17:21:52 +08008216 layer_blend = &blending->layer_blend;
8217 osd_log_dbg2(MODULE_BLEND, "%s input1_data:%d,%d,%d,%d\n",
8218 __func__,
8219 layer_blend->input1_data.x,
8220 layer_blend->input1_data.y,
8221 layer_blend->input1_data.w,
8222 layer_blend->input1_data.h);
8223 osd_log_dbg2(MODULE_BLEND, "%s input2_data:%d,%d,%d,%d\n",
8224 __func__,
8225 layer_blend->input2_data.x,
8226 layer_blend->input2_data.y,
8227 layer_blend->input2_data.w,
8228 layer_blend->input2_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008229
8230 input1_end_x = layer_blend->input1_data.x +
8231 layer_blend->input1_data.w - 1;
8232 input1_end_y = layer_blend->input1_data.y +
8233 layer_blend->input1_data.h - 1;
8234 input2_end_x = layer_blend->input2_data.x +
8235 layer_blend->input2_data.w - 1;
8236 input2_end_y = layer_blend->input2_data.y +
8237 layer_blend->input2_data.h - 1;
8238 if (layer_blend->input1_data.x < layer_blend->input2_data.x)
8239 layer_blend->output_data.x = layer_blend->input1_data.x;
8240 else
8241 layer_blend->output_data.x = layer_blend->input2_data.x;
8242 if (layer_blend->input1_data.y < layer_blend->input2_data.y)
8243 layer_blend->output_data.y = layer_blend->input1_data.y;
8244 else
8245 layer_blend->output_data.y = layer_blend->input2_data.y;
8246
8247 if (input1_end_x < input2_end_x)
8248 output_end_x = input2_end_x;
8249 else
8250 output_end_x = input1_end_x;
8251 if (input1_end_y < input2_end_y)
8252 output_end_y = input2_end_y;
8253 else
8254 output_end_y = input1_end_y;
8255 layer_blend->output_data.x = 0;
8256 layer_blend->output_data.y = 0;
8257 layer_blend->output_data.w = output_end_x -
8258 layer_blend->output_data.x + 1;
8259 layer_blend->output_data.h = output_end_y -
8260 layer_blend->output_data.y + 1;
8261}
8262
8263static void osd_setting_blend0(struct hw_osd_blending_s *blending)
8264{
Googler9398cc32022-12-02 17:21:52 +08008265 struct osd_blend_reg_s *osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008266 struct layer_blend_s *layer_blend;
8267 u32 index = 0;
8268 u32 bld_osd_h_start = 0, bld_osd_h_end = 0;
8269 u32 bld_osd_v_start = 0, bld_osd_v_end = 0;
Googler9398cc32022-12-02 17:21:52 +08008270 u32 blend_hsize, blend_vsize;
Googler4f18c0c2022-09-20 17:23:36 +08008271
8272 if (!blending)
8273 return;
Googler9398cc32022-12-02 17:21:52 +08008274 layer_blend = &blending->layer_blend;
8275 osd_blend_reg = &blending->osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008276 /* blend0 only accept input1 */
8277 if (layer_blend->input1 & BYPASS_DIN) {
Googler9398cc32022-12-02 17:21:52 +08008278 osd_blend_reg->din0_byp_blend = 1;
Googler4f18c0c2022-09-20 17:23:36 +08008279 layer_blend->input1 &= ~BYPASS_DIN;
Googler9398cc32022-12-02 17:21:52 +08008280 } else if (layer_blend->input2 & BYPASS_DIN) {
8281 osd_blend_reg->din0_byp_blend = 1;
8282 layer_blend->input2 &= ~BYPASS_DIN;
8283 } else {
8284 osd_blend_reg->din0_byp_blend = 0;
8285 }
Googler4f18c0c2022-09-20 17:23:36 +08008286 if (layer_blend->input1 != BLEND_NO_DIN) {
8287 /* calculate osd blend din scope */
8288 index = blend_din_to_osd(layer_blend->input1, blending);
8289 if (index >= OSD_MAX)
8290 return;
8291 bld_osd_h_start =
8292 layer_blend->input1_data.x;
8293 bld_osd_h_end =
8294 layer_blend->input1_data.x +
8295 layer_blend->input1_data.w - 1;
8296 bld_osd_v_start =
8297 layer_blend->input1_data.y;
8298 bld_osd_v_end =
8299 layer_blend->input1_data.y +
8300 layer_blend->input1_data.h - 1;
Googler9398cc32022-12-02 17:21:52 +08008301 osd_blend_reg->osd_blend_din_scope_h[index] =
Googler4f18c0c2022-09-20 17:23:36 +08008302 bld_osd_h_end << 16 | bld_osd_h_start;
Googler9398cc32022-12-02 17:21:52 +08008303 osd_blend_reg->osd_blend_din_scope_v[index] =
Googler4f18c0c2022-09-20 17:23:36 +08008304 bld_osd_v_end << 16 | bld_osd_v_start;
Googler9398cc32022-12-02 17:21:52 +08008305 osd_log_dbg2(MODULE_BLEND,
8306 "blend0:input1_data[osd%d]:%d,%d,%d,%d\n",
8307 index,
8308 layer_blend->input1_data.x,
8309 layer_blend->input1_data.y,
8310 layer_blend->input1_data.w,
8311 layer_blend->input1_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008312 }
Googler9398cc32022-12-02 17:21:52 +08008313 if (layer_blend->input2 != BLEND_NO_DIN) {
8314 /* calculate osd blend din scope */
8315 index = blend_din_to_osd(layer_blend->input2, blending);
8316 if (index >= OSD_MAX)
8317 return;
8318 bld_osd_h_start =
8319 layer_blend->input2_data.x;
8320 bld_osd_h_end =
8321 layer_blend->input2_data.x +
8322 layer_blend->input2_data.w - 1;
8323 bld_osd_v_start =
8324 layer_blend->input2_data.y;
8325 bld_osd_v_end =
8326 layer_blend->input2_data.y +
8327 layer_blend->input2_data.h - 1;
8328 osd_blend_reg->osd_blend_din_scope_h[index] =
8329 bld_osd_h_end << 16 | bld_osd_h_start;
8330 osd_blend_reg->osd_blend_din_scope_v[index] =
8331 bld_osd_v_end << 16 | bld_osd_v_start;
8332 osd_log_dbg2(MODULE_BLEND,
8333 "blend0:input2_data[osd%d]:%d,%d,%d,%d\n",
8334 index,
8335 layer_blend->input2_data.x,
8336 layer_blend->input2_data.y,
8337 layer_blend->input2_data.w,
8338 layer_blend->input2_data.h);
8339 }
8340 if (osd_blend_reg->din0_byp_blend ||
8341 layer_blend->input1 == BLEND_NO_DIN ||
8342 layer_blend->input2 == BLEND_NO_DIN) {
8343 /* blend din3 bypass,output == input */
8344 if (layer_blend->input1 == BLEND_NO_DIN)
8345 memcpy(&layer_blend->output_data,
8346 &layer_blend->input2_data,
8347 sizeof(struct dispdata_s));
8348 else
8349 memcpy(&layer_blend->output_data,
8350 &layer_blend->input1_data,
8351 sizeof(struct dispdata_s));
8352 } else {
8353 calc_max_output(blending);
8354 }
8355 blend_hsize = layer_blend->output_data.w;
8356 blend_vsize = layer_blend->output_data.h;
8357 osd_blend_reg->osd_blend_blend0_size =
8358 blend_vsize << 16 | blend_hsize;
Googler4f18c0c2022-09-20 17:23:36 +08008359 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08008360 "blend0:layer_blend->output_data:%d,%d,%d,%d\n",
8361 layer_blend->output_data.x,
8362 layer_blend->output_data.y,
8363 layer_blend->output_data.w,
8364 layer_blend->output_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008365}
8366
8367static void osd_setting_blend1(struct hw_osd_blending_s *blending)
8368{
8369 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +08008370 struct osd_blend_reg_s *osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008371 u32 index = 0;
8372 u32 blend_hsize, blend_vsize;
8373 u32 bld_osd_h_start = 0, bld_osd_h_end = 0;
8374 u32 bld_osd_v_start = 0, bld_osd_v_end = 0;
8375 u32 workaround_line = 0;
8376 /* for g12a blend shift issue */
8377
8378 if (!blending)
8379 return;
Googler9398cc32022-12-02 17:21:52 +08008380 if (osd_hw.hdr_used) {
Googler4f18c0c2022-09-20 17:23:36 +08008381 workaround_line = osd_hw.workaround_line;
Googler9398cc32022-12-02 17:21:52 +08008382 } else {
Googler4f18c0c2022-09-20 17:23:36 +08008383 if (blending->layer_cnt == 2)
8384 workaround_line = 0;
8385 else
8386 workaround_line = osd_hw.workaround_line;
8387 }
Googler9398cc32022-12-02 17:21:52 +08008388 layer_blend = &blending->layer_blend;
8389 osd_blend_reg = &blending->osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008390
Googler9398cc32022-12-02 17:21:52 +08008391 if (layer_blend->input1 & BYPASS_DIN) {
8392 /* blend1_din2 bypass to dout1 */
8393 osd_blend_reg->din2_osd_sel = 1;
8394 layer_blend->input1 &= ~BYPASS_DIN;
8395 } else {
8396 /* blend1_dout to blend2 */
8397 osd_blend_reg->din2_osd_sel = 0;
8398 }
Googler4f18c0c2022-09-20 17:23:36 +08008399 if (layer_blend->input2 & BYPASS_DIN) {
8400 /* blend1_din3 bypass to dout1 */
Googler9398cc32022-12-02 17:21:52 +08008401 osd_blend_reg->din3_osd_sel = 1;
Googler4f18c0c2022-09-20 17:23:36 +08008402 layer_blend->input2 &= ~BYPASS_DIN;
Googler9398cc32022-12-02 17:21:52 +08008403 } else {
Googler4f18c0c2022-09-20 17:23:36 +08008404 /* blend1_din3 input to blend1 */
Googler9398cc32022-12-02 17:21:52 +08008405 osd_blend_reg->din3_osd_sel = 0;
8406 }
Googler4f18c0c2022-09-20 17:23:36 +08008407
8408 if (layer_blend->input1 != BLEND_NO_DIN) {
8409 index = blend_din_to_osd(layer_blend->input1, blending);
8410 if (index >= OSD_MAX)
8411 return;
8412 /* calculate osd blend din scope */
8413 bld_osd_h_start =
8414 layer_blend->input1_data.x;
8415 bld_osd_h_end =
8416 layer_blend->input1_data.x +
8417 layer_blend->input1_data.w - 1;
8418 bld_osd_v_start =
8419 layer_blend->input1_data.y;
8420 bld_osd_v_end =
8421 layer_blend->input1_data.y +
8422 layer_blend->input1_data.h - 1;
Googler9398cc32022-12-02 17:21:52 +08008423 osd_blend_reg->osd_blend_din_scope_h[index] =
Googler4f18c0c2022-09-20 17:23:36 +08008424 bld_osd_h_end << 16 | bld_osd_h_start;
Googler9398cc32022-12-02 17:21:52 +08008425 osd_blend_reg->osd_blend_din_scope_v[index] =
Googler4f18c0c2022-09-20 17:23:36 +08008426 bld_osd_v_end << 16 | bld_osd_v_start;
8427 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08008428 "blend1:input1_data[osd%d]:%d,%d,%d,%d\n",
8429 index,
8430 layer_blend->input1_data.x,
8431 layer_blend->input1_data.y,
8432 layer_blend->input1_data.w,
8433 layer_blend->input1_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008434 }
8435 if (layer_blend->input2 != BLEND_NO_DIN) {
8436 index = blend_din_to_osd(layer_blend->input2, blending);
8437 if (index >= OSD_MAX)
8438 return;
8439 /* calculate osd blend din scope */
8440 bld_osd_h_start =
8441 layer_blend->input2_data.x;
8442 bld_osd_h_end =
8443 layer_blend->input2_data.x +
8444 layer_blend->input2_data.w - 1;
8445 bld_osd_v_start =
8446 layer_blend->input2_data.y;
8447 bld_osd_v_end =
8448 layer_blend->input2_data.y +
8449 layer_blend->input2_data.h - 1;
Googler9398cc32022-12-02 17:21:52 +08008450 osd_blend_reg->osd_blend_din_scope_h[index] =
Googler4f18c0c2022-09-20 17:23:36 +08008451 bld_osd_h_end << 16 | bld_osd_h_start;
Googler9398cc32022-12-02 17:21:52 +08008452 osd_blend_reg->osd_blend_din_scope_v[index] =
Googler4f18c0c2022-09-20 17:23:36 +08008453 bld_osd_v_end << 16 | bld_osd_v_start;
8454 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08008455 "blend1:input2_data[osd%d]:%d,%d,%d,%d\n",
8456 index,
8457 layer_blend->input2_data.x,
8458 layer_blend->input2_data.y,
8459 layer_blend->input2_data.w,
8460 layer_blend->input2_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008461 }
Googler9398cc32022-12-02 17:21:52 +08008462 if (osd_blend_reg->din3_osd_sel || layer_blend->input1 == BLEND_NO_DIN) {
Googler4f18c0c2022-09-20 17:23:36 +08008463 /* blend din3 bypass,output == input */
Googler9398cc32022-12-02 17:21:52 +08008464 if (layer_blend->input2 == BLEND_NO_DIN) {
8465 memcpy(&layer_blend->output_data,
8466 &layer_blend->input1_data,
8467 sizeof(struct dispdata_s));
8468 } else {
8469 memcpy(&layer_blend->output_data,
8470 &layer_blend->input2_data,
8471 sizeof(struct dispdata_s));
8472 }
8473 layer_blend->output_data.h += workaround_line;
Googler9726be62022-12-14 05:53:31 +00008474
Googler9398cc32022-12-02 17:21:52 +08008475 } else {
Googler9726be62022-12-14 05:53:31 +00008476 calc_max_output(blending);
Googler9398cc32022-12-02 17:21:52 +08008477 }
Googler4f18c0c2022-09-20 17:23:36 +08008478 blend_hsize = layer_blend->output_data.w;
8479 blend_vsize = layer_blend->output_data.h;
Googler9398cc32022-12-02 17:21:52 +08008480 osd_blend_reg->osd_blend_blend1_size =
Googler4f18c0c2022-09-20 17:23:36 +08008481 blend_vsize << 16 | blend_hsize;
8482
Googler9398cc32022-12-02 17:21:52 +08008483 osd_log_dbg2(MODULE_BLEND, "blend1:layer_blend->output_data:%d,%d,%d,%d\n",
8484 layer_blend->output_data.x,
8485 layer_blend->output_data.y,
8486 layer_blend->output_data.w,
8487 layer_blend->output_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008488}
8489
8490static void osd_setting_blend2(struct hw_osd_blending_s *blending)
8491{
8492 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +08008493 struct osd_blend_reg_s *osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008494 u32 blend_hsize, blend_vsize;
8495 int blend1_input = 0;
8496
8497 if (!blending)
8498 return;
Googler9398cc32022-12-02 17:21:52 +08008499 layer_blend = &blending->layer_blend;
8500 osd_blend_reg = &blending->osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008501
8502 blend_hsize = layer_blend->input1_data.w;
8503 blend_vsize = layer_blend->input1_data.h;
8504 /* always used input1_data */
8505 /* osd_blend_blend0_size share with blend2_size*/
Googler9398cc32022-12-02 17:21:52 +08008506 osd_blend_reg->osd_blend_blend0_size =
Googler4f18c0c2022-09-20 17:23:36 +08008507 blend_vsize << 16 | blend_hsize;
8508 switch (layer_blend->input2) {
8509 case BLEND1_DIN:
8510 blend1_input = 0;
8511 break;
8512 default:
8513 /* blend1_dout to dout1 */
8514 blend1_input = 1;
8515 break;
8516 }
8517
8518 /* premult set */
Googler9398cc32022-12-02 17:21:52 +08008519 osd_blend_reg->blend2_premult_en = 3;
8520 if (blend1_input) {
8521 memcpy(&layer_blend->output_data, &layer_blend->input1_data,
8522 sizeof(struct dispdata_s));
8523 } else {
Googler4f18c0c2022-09-20 17:23:36 +08008524 calc_max_output(blending);
8525 blend_hsize = layer_blend->output_data.w;
8526 blend_vsize = layer_blend->output_data.h;
Googler9398cc32022-12-02 17:21:52 +08008527 osd_blend_reg->osd_blend_blend0_size =
Googler4f18c0c2022-09-20 17:23:36 +08008528 blend_vsize << 16 | blend_hsize;
8529 /* blend 0 and blend1 size need same */
Googler9398cc32022-12-02 17:21:52 +08008530 osd_blend_reg->osd_blend_blend1_size =
8531 osd_blend_reg->osd_blend_blend0_size;
Googler4f18c0c2022-09-20 17:23:36 +08008532 }
8533 osd_log_dbg2(MODULE_BLEND, "layer_blend2->output_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +08008534 layer_blend->output_data.x,
8535 layer_blend->output_data.y,
8536 layer_blend->output_data.w,
8537 layer_blend->output_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008538}
8539
8540static void vpp_setting_blend(struct hw_osd_blending_s *blending)
8541{
8542 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +08008543 struct osd_blend_reg_s *osd_blend_reg;
8544 struct vpp0_blend_reg_s *vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008545 u32 osd1_h_start = 0, osd1_h_end = 0;
8546 u32 osd1_v_start = 0, osd1_v_end = 0;
8547 u32 osd2_h_start = 0, osd2_h_end = 0;
8548 u32 osd2_v_start = 0, osd2_v_end = 0;
Googler9726be62022-12-14 05:53:31 +00008549 u32 postbld_src3_sel = 0, postbld_osd1_premult = 0;
8550 u32 postbld_src4_sel = 0, postbld_osd2_premult = 0;
Googler4f18c0c2022-09-20 17:23:36 +08008551
8552 if (!blending)
8553 return;
Googler9398cc32022-12-02 17:21:52 +08008554 layer_blend = &blending->layer_blend;
8555 osd_blend_reg = &blending->osd_blend_reg;
8556 vpp0_blend_reg = &blending->vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008557
8558 osd1_h_start = layer_blend->input1_data.x;
8559 osd1_h_end = layer_blend->input1_data.x +
8560 layer_blend->input1_data.w - 1;
8561 osd1_v_start = layer_blend->input1_data.y;
8562 osd1_v_end = layer_blend->input1_data.y +
8563 layer_blend->input1_data.h - 1;
8564 osd2_h_start = layer_blend->input2_data.x;
8565 osd2_h_end = layer_blend->input2_data.x +
8566 layer_blend->input2_data.w - 1;
8567 osd2_v_start = layer_blend->input2_data.y;
8568 osd2_v_end = layer_blend->input2_data.y +
8569 layer_blend->input2_data.h - 1;
8570 /* vpp osd1 postblend scope */
8571 switch (layer_blend->input1) {
8572 case BLEND1_DIN:
Googler9398cc32022-12-02 17:21:52 +08008573 if (osd_dev_hw.t7_display)
8574 postbld_src3_sel = POSTBLD_OSD2_T7;
8575 else
8576 postbld_src3_sel = POSTBLD_OSD2;
Googler38bda472022-08-19 10:07:08 -07008577 if (layer_blend->blend_core1_bypass)
Googler9726be62022-12-14 05:53:31 +00008578 postbld_osd1_premult = 0;
Googler38bda472022-08-19 10:07:08 -07008579 else
Googler9726be62022-12-14 05:53:31 +00008580 postbld_osd1_premult = 1;
Googler9398cc32022-12-02 17:21:52 +08008581 vpp0_blend_reg->osd1_h_start = osd2_h_start;
8582 vpp0_blend_reg->osd1_h_end = osd2_h_end;
8583 vpp0_blend_reg->osd1_v_start = osd2_v_start;
8584 vpp0_blend_reg->osd1_v_end = osd2_v_end;
8585 vpp0_blend_reg->osd1_index = VPP_OSD1;
Googler4f18c0c2022-09-20 17:23:36 +08008586 break;
8587 case BLEND2_DIN:
Googler9398cc32022-12-02 17:21:52 +08008588 if (osd_dev_hw.t7_display)
8589 postbld_src3_sel = POSTBLD_OSD1_T7;
8590 else
8591 postbld_src3_sel = POSTBLD_OSD1;
8592 if (osd_blend_reg->din0_byp_blend)
Googler9726be62022-12-14 05:53:31 +00008593 postbld_osd1_premult = 0;
Googler38bda472022-08-19 10:07:08 -07008594 else
Googler9726be62022-12-14 05:53:31 +00008595 postbld_osd1_premult = 1;
Googler9398cc32022-12-02 17:21:52 +08008596 vpp0_blend_reg->osd1_h_start = osd1_h_start;
8597 vpp0_blend_reg->osd1_h_end = osd1_h_end;
8598 vpp0_blend_reg->osd1_v_start = osd1_v_start;
8599 vpp0_blend_reg->osd1_v_end = osd1_v_end;
8600 vpp0_blend_reg->osd1_index = VPP_OSD1;
Googler4f18c0c2022-09-20 17:23:36 +08008601 break;
8602 default:
Googler9726be62022-12-14 05:53:31 +00008603 postbld_src3_sel = POSTBLD_CLOSE;
8604 postbld_osd1_premult = 0;
Googler9398cc32022-12-02 17:21:52 +08008605 vpp0_blend_reg->osd1_index = VPP_DIN_NONE;
Googler4f18c0c2022-09-20 17:23:36 +08008606 break;
8607 }
8608 /* vpp osd2 postblend scope */
8609 switch (layer_blend->input2) {
8610 case BLEND1_DIN:
Googler9398cc32022-12-02 17:21:52 +08008611 if (osd_dev_hw.t7_display)
8612 postbld_src4_sel = POSTBLD_OSD2_T7;
8613 else
8614 postbld_src4_sel = POSTBLD_OSD2;
Googler38bda472022-08-19 10:07:08 -07008615 if (layer_blend->blend_core1_bypass)
Googler9726be62022-12-14 05:53:31 +00008616 postbld_osd2_premult = 0;
Googler38bda472022-08-19 10:07:08 -07008617 else
Googler9726be62022-12-14 05:53:31 +00008618 postbld_osd2_premult = 1;
Googler9398cc32022-12-02 17:21:52 +08008619 vpp0_blend_reg->osd2_h_start = osd2_h_start;
8620 vpp0_blend_reg->osd2_h_end = osd2_h_end;
8621 vpp0_blend_reg->osd2_v_start = osd2_v_start;
8622 vpp0_blend_reg->osd2_v_end = osd2_v_end;
8623 vpp0_blend_reg->osd2_index = VPP_OSD3;
Googler4f18c0c2022-09-20 17:23:36 +08008624 break;
8625 case BLEND2_DIN:
Googler9398cc32022-12-02 17:21:52 +08008626 if (osd_dev_hw.t7_display)
8627 postbld_src4_sel = POSTBLD_OSD1_T7;
8628 else
8629 postbld_src4_sel = POSTBLD_OSD1;
8630 if (osd_blend_reg->din0_byp_blend)
Googler9726be62022-12-14 05:53:31 +00008631 postbld_osd2_premult = 0;
Googler38bda472022-08-19 10:07:08 -07008632 else
Googler9726be62022-12-14 05:53:31 +00008633 postbld_osd2_premult = 1;
Googler9398cc32022-12-02 17:21:52 +08008634 vpp0_blend_reg->osd2_h_start = osd1_h_start;
8635 vpp0_blend_reg->osd2_h_end = osd1_h_end;
8636 vpp0_blend_reg->osd2_v_start = osd1_v_start;
8637 vpp0_blend_reg->osd2_v_end = osd1_v_end;
8638 vpp0_blend_reg->osd2_index = VPP_OSD3;
Googler4f18c0c2022-09-20 17:23:36 +08008639 break;
8640 default:
Googler9726be62022-12-14 05:53:31 +00008641 postbld_src4_sel = POSTBLD_CLOSE;
8642 postbld_osd2_premult = 0;
Googler9398cc32022-12-02 17:21:52 +08008643 vpp0_blend_reg->osd2_index = VPP_DIN_NONE;
Googler4f18c0c2022-09-20 17:23:36 +08008644 break;
8645 }
Googler9726be62022-12-14 05:53:31 +00008646 if (osd_hw.osd_preblend_en) {
Googler9398cc32022-12-02 17:21:52 +08008647 vpp0_blend_reg->prebld_src3_sel = postbld_src3_sel;
8648 vpp0_blend_reg->prebld_osd1_premult = postbld_osd1_premult;
8649 vpp0_blend_reg->prebld_src4_sel = postbld_src4_sel;
8650 vpp0_blend_reg->prebld_osd2_premult = postbld_osd2_premult;
Googler9726be62022-12-14 05:53:31 +00008651 if (osd_hw.osd_preblend_en == 1)
Googler9398cc32022-12-02 17:21:52 +08008652 vpp0_blend_reg->postbld_src3_sel = 1;
Googler9726be62022-12-14 05:53:31 +00008653 else if (osd_hw.osd_preblend_en == 2)
Googler9398cc32022-12-02 17:21:52 +08008654 vpp0_blend_reg->postbld_src3_sel = 0;
8655 vpp0_blend_reg->postbld_osd1_premult = 0;
8656 vpp0_blend_reg->postbld_src4_sel = 0;
8657 vpp0_blend_reg->postbld_osd2_premult = 0;
Googler9726be62022-12-14 05:53:31 +00008658 } else {
Googler9398cc32022-12-02 17:21:52 +08008659 vpp0_blend_reg->prebld_src3_sel = 0;
8660 vpp0_blend_reg->prebld_osd1_premult = 0;
8661 vpp0_blend_reg->prebld_src4_sel = 0;
8662 vpp0_blend_reg->prebld_osd2_premult = 0;
8663 vpp0_blend_reg->postbld_src3_sel = postbld_src3_sel;
8664 vpp0_blend_reg->postbld_osd1_premult = postbld_osd1_premult;
8665 vpp0_blend_reg->postbld_src4_sel = postbld_src4_sel;
8666 vpp0_blend_reg->postbld_osd2_premult = postbld_osd2_premult;
Googler9726be62022-12-14 05:53:31 +00008667 }
Googler9398cc32022-12-02 17:21:52 +08008668
8669 if (vpp0_blend_reg->postbld_osd1_premult ||
8670 vpp0_blend_reg->prebld_osd1_premult)
8671 osd_blend_reg->osd_bld_out0_premult = 1;
8672 if (vpp0_blend_reg->postbld_osd2_premult ||
8673 vpp0_blend_reg->prebld_osd2_premult)
8674 osd_blend_reg->osd_bld_out1_premult = 1;
8675
Googler4f18c0c2022-09-20 17:23:36 +08008676 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08008677 "vpp input1: x=%d, y=%d, w=%d, h=%d\n",
8678 layer_blend->input1_data.x,
8679 layer_blend->input1_data.y,
8680 layer_blend->input1_data.w,
8681 layer_blend->input1_data.h);
Googler4f18c0c2022-09-20 17:23:36 +08008682 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08008683 "vpp input2: x=%d, y=%d, w=%d, h=%d\n",
8684 layer_blend->input2_data.x,
8685 layer_blend->input2_data.y,
8686 layer_blend->input2_data.w,
8687 layer_blend->input2_data.h);
8688
8689 osd_log_dbg2(MODULE_BLEND,
8690 "vpp_osd1_blend size=%d,%d,%d,%d\n",
8691 vpp0_blend_reg->osd1_h_start,
8692 vpp0_blend_reg->osd1_h_end,
8693 vpp0_blend_reg->osd1_v_start,
8694 vpp0_blend_reg->osd1_v_end);
8695 osd_log_dbg2(MODULE_BLEND,
8696 "vpp_osd2_blend size=%d,%d,%d,%d\n",
8697 vpp0_blend_reg->osd2_h_start,
8698 vpp0_blend_reg->osd2_h_end,
8699 vpp0_blend_reg->osd2_v_start,
8700 vpp0_blend_reg->osd2_v_end);
Googler9726be62022-12-14 05:53:31 +00008701}
8702
8703static void set_osd_dummy_policy(u32 index, u32 src_height, u32 dst_height)
8704{
8705 u32 output_index;
8706
8707 output_index = get_output_device_id(index);
8708
Googler9398cc32022-12-02 17:21:52 +08008709 if (index == OSD1) {
8710 if (osd_hw.osd_meson_dev.cpu_id ==
8711 __MESON_CPU_MAJOR_ID_G12A &&
8712 dst_height != src_height &&
8713 osd_hw.free_dst_data[index].y_end <
8714 osd_hw.vinfo_height[output_index] - 1)
Googler9726be62022-12-14 05:53:31 +00008715 osd_set_dummy_data(index, 0);
Googler9398cc32022-12-02 17:21:52 +08008716 else
Googler9726be62022-12-14 05:53:31 +00008717 osd_set_dummy_data(index, 0xff);
Googler9398cc32022-12-02 17:21:52 +08008718 } else {
8719 if (osd_hw.osd_meson_dev.cpu_id ==
8720 __MESON_CPU_MAJOR_ID_G12A &&
8721 osd_hw.free_dst_data[index].y_end <
8722 osd_hw.vinfo_height[output_index] - 1)
8723 osd_set_dummy_data(index, 0);
8724 else
8725 osd_set_dummy_data(index, 0xff);
8726 }
Googler38bda472022-08-19 10:07:08 -07008727}
8728
8729/* input w, h is background */
Googler4f18c0c2022-09-20 17:23:36 +08008730static void osd_set_freescale(u32 index,
Googler9398cc32022-12-02 17:21:52 +08008731 struct hw_osd_blending_s *blending)
Googler4f18c0c2022-09-20 17:23:36 +08008732
8733{
8734 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +08008735 struct osd_blend_reg_s *osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008736 u32 width, height;
8737 u32 src_height;
8738 u32 workaround_line = osd_hw.workaround_line;
8739 u32 output_index = 0;
8740
Googler9398cc32022-12-02 17:21:52 +08008741 layer_blend = &blending->layer_blend;
8742 osd_blend_reg = &blending->osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008743 if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
8744 osd_log_err("error osd index=%d\n", index);
8745 return;
8746 }
Googler9726be62022-12-14 05:53:31 +00008747 if (!(osd_hw.osd_display_debug[output_index] &&
Googler9398cc32022-12-02 17:21:52 +08008748 !osd_hw.free_scale_enable[index])) {
Googler9726be62022-12-14 05:53:31 +00008749 osd_hw.free_scale_enable[index] = 0x10001;
8750 osd_hw.free_scale[index].h_enable = 1;
8751 osd_hw.free_scale[index].v_enable = 1;
8752 osd_hw.free_scale_mode[index] = 1;
8753 }
Googler4f18c0c2022-09-20 17:23:36 +08008754 output_index = get_output_device_id(index);
8755
8756 if (index == OSD1) {
8757 osd_hw.free_src_data[index].x_start =
8758 layer_blend->output_data.x;
8759 osd_hw.free_src_data[index].x_end =
8760 layer_blend->output_data.x +
8761 layer_blend->output_data.w - 1;
8762 osd_hw.free_src_data[index].y_start =
8763 layer_blend->output_data.y;
8764 osd_hw.free_src_data[index].y_end =
8765 layer_blend->output_data.y +
8766 layer_blend->output_data.h - 1;
8767
8768 osd_hw.free_dst_data[index].x_start = 0;
8769 osd_hw.free_dst_data[index].y_start = 0;
Googler9726be62022-12-14 05:53:31 +00008770 width = layer_blend->output_data.w *
8771 blending->screen_ratio_w_num /
8772 blending->screen_ratio_w_den;
8773 height = (layer_blend->output_data.h - workaround_line) *
8774 blending->screen_ratio_h_num /
8775 blending->screen_ratio_h_den;
Googler4f18c0c2022-09-20 17:23:36 +08008776 if (osd_hw.field_out_en[output_index])
8777 height = height >> 1;
8778 } else {
8779 osd_hw.free_src_data[index].x_start =
8780 osd_hw.src_data[index].x;
8781 osd_hw.free_src_data[index].x_end =
8782 osd_hw.src_data[index].x +
8783 osd_hw.src_data[index].w - 1;
8784 osd_hw.free_src_data[index].y_start =
8785 osd_hw.src_data[index].y;
8786 osd_hw.free_src_data[index].y_end =
8787 osd_hw.src_data[index].y +
8788 osd_hw.src_data[index].h - 1;
Googler9726be62022-12-14 05:53:31 +00008789 if (osd_hw.osd_v_skip[index]) {
8790 osd_hw.free_src_data[index].y_end =
8791 (osd_hw.src_data[index].y +
8792 osd_hw.src_data[index].h) / 2 - 1;
8793 }
Googler4f18c0c2022-09-20 17:23:36 +08008794
Googler9398cc32022-12-02 17:21:52 +08008795 if (blending->osd_blend_mode == OSD_BLEND_AC ||
8796 blending->osd_blend_mode == OSD_BLEND_ABC ||
8797 blending->osd_blend_mode == OSD_BLEND_ABCD) {
Googler4f18c0c2022-09-20 17:23:36 +08008798 /* combine mode, need uniformization */
8799 osd_hw.free_dst_data[index].x_start =
Googler9726be62022-12-14 05:53:31 +00008800 osd_hw.dst_data[index].x *
8801 blending->screen_ratio_w_den /
8802 blending->screen_ratio_w_num;
Googler4f18c0c2022-09-20 17:23:36 +08008803 osd_hw.free_dst_data[index].y_start =
Googler9726be62022-12-14 05:53:31 +00008804 osd_hw.dst_data[index].y *
8805 blending->screen_ratio_h_den /
8806 blending->screen_ratio_h_num;
8807 width = osd_hw.dst_data[index].w *
8808 blending->screen_ratio_w_den /
8809 blending->screen_ratio_w_num;
8810 height = osd_hw.dst_data[index].h *
8811 blending->screen_ratio_h_den /
8812 blending->screen_ratio_h_num;
Googler4f18c0c2022-09-20 17:23:36 +08008813 } else if (blending->osd_blend_mode == OSD_BLEND_AB_C) {
8814 osd_log_dbg(MODULE_BLEND, "blending->blend_din=%d\n",
Googler9398cc32022-12-02 17:21:52 +08008815 blending->blend_din);
Googler4f18c0c2022-09-20 17:23:36 +08008816 if (blending->blend_din != BLEND_DIN4) {
8817 /* combine mode, need uniformization */
8818 osd_hw.free_dst_data[index].x_start =
Googler9726be62022-12-14 05:53:31 +00008819 osd_hw.dst_data[index].x *
8820 blending->screen_ratio_w_den /
8821 blending->screen_ratio_w_num;
Googler4f18c0c2022-09-20 17:23:36 +08008822 osd_hw.free_dst_data[index].y_start =
Googler9726be62022-12-14 05:53:31 +00008823 osd_hw.dst_data[index].y *
8824 blending->screen_ratio_h_den /
8825 blending->screen_ratio_h_num;
8826 width = osd_hw.dst_data[index].w *
8827 blending->screen_ratio_w_den /
8828 blending->screen_ratio_w_num;
8829 height = osd_hw.dst_data[index].h *
8830 blending->screen_ratio_h_den /
8831 blending->screen_ratio_h_num;
Googler4f18c0c2022-09-20 17:23:36 +08008832 } else {
8833 /* direct used dst as freescale dst */
8834 osd_hw.free_dst_data[index].x_start =
8835 osd_hw.dst_data[index].x;
8836 osd_hw.free_dst_data[index].y_start =
8837 osd_hw.dst_data[index].y;
8838 width = osd_hw.dst_data[index].w;
8839 height = osd_hw.dst_data[index].h;
8840 /* interleaced case */
8841 if (osd_hw.field_out_en[output_index]) {
8842 height = height >> 1;
Googler9398cc32022-12-02 17:21:52 +08008843 osd_hw.free_dst_data[index].y_start >>= 1;
Googler4f18c0c2022-09-20 17:23:36 +08008844 }
8845 }
8846 } else {
8847 /* direct used dst as freescale dst */
8848 osd_hw.free_dst_data[index].x_start =
8849 osd_hw.dst_data[index].x;
8850 osd_hw.free_dst_data[index].y_start =
8851 osd_hw.dst_data[index].y;
8852 width = osd_hw.dst_data[index].w;
8853 height = osd_hw.dst_data[index].h;
8854 if (osd_hw.field_out_en[output_index]) {
8855 height = height >> 1;
8856 osd_hw.free_dst_data[index].y_start >>= 1;
8857 }
8858 }
8859 }
8860 osd_hw.free_dst_data[index].x_end =
8861 osd_hw.free_dst_data[index].x_start +
8862 width - 1;
8863 osd_hw.free_dst_data[index].y_end =
8864 osd_hw.free_dst_data[index].y_start +
8865 height - 1;
8866
8867 src_height = osd_hw.free_src_data[index].x_end -
8868 osd_hw.free_src_data[index].x_start + 1;
Googler9726be62022-12-14 05:53:31 +00008869 set_osd_dummy_policy(index, src_height, height);
Googler4f18c0c2022-09-20 17:23:36 +08008870 osd_log_dbg2(MODULE_BLEND, "osd%d:free_src_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +08008871 index,
8872 osd_hw.free_src_data[index].x_start,
8873 osd_hw.free_src_data[index].y_start,
8874 osd_hw.free_src_data[index].x_end,
8875 osd_hw.free_src_data[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +08008876 osd_log_dbg2(MODULE_BLEND, "osd%d:free_dst_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +08008877 index,
8878 osd_hw.free_dst_data[index].x_start,
8879 osd_hw.free_dst_data[index].y_start,
8880 osd_hw.free_dst_data[index].x_end,
8881 osd_hw.free_dst_data[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +08008882}
8883
8884static void osd_setting_blend0_input(u32 index,
Googler9398cc32022-12-02 17:21:52 +08008885 struct hw_osd_blending_s *blending)
Googler4f18c0c2022-09-20 17:23:36 +08008886{
8887 struct layer_blend_s *layer_blend;
8888 u32 workaround_line = 0;
8889 /* for g12a blend shift issue */
8890
8891 workaround_line = osd_hw.workaround_line;
Googler9398cc32022-12-02 17:21:52 +08008892 layer_blend = &blending->layer_blend;
Googler4f18c0c2022-09-20 17:23:36 +08008893 if (index == OSD1) {
Googler9398cc32022-12-02 17:21:52 +08008894 layer_blend->output_data.x =
8895 blending->dst_data.x;
8896 layer_blend->output_data.y =
8897 blending->dst_data.y
Googler4f18c0c2022-09-20 17:23:36 +08008898 + workaround_line;
Googler9398cc32022-12-02 17:21:52 +08008899 layer_blend->output_data.w =
8900 blending->dst_data.w;
8901 layer_blend->output_data.h =
8902 blending->dst_data.h;
Googler38bda472022-08-19 10:07:08 -07008903 } else {
8904 layer_blend->output_data.x =
8905 osd_hw.free_dst_data[index].x_start;
8906 layer_blend->output_data.y =
8907 osd_hw.free_dst_data[index].y_start
8908 + workaround_line;
8909 layer_blend->output_data.w =
8910 osd_hw.free_dst_data[index].x_end -
8911 osd_hw.free_dst_data[index].x_start + 1;
8912 layer_blend->output_data.h =
8913 osd_hw.free_dst_data[index].y_end -
8914 osd_hw.free_dst_data[index].y_start + 1;
8915 }
8916 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08008917 "blend0_input:input_data[osd%d]:%d,%d,%d,%d\n",
8918 index,
8919 layer_blend->output_data.x,
8920 layer_blend->output_data.y,
8921 layer_blend->output_data.w,
8922 layer_blend->output_data.h);
Googler38bda472022-08-19 10:07:08 -07008923}
8924
Googler9398cc32022-12-02 17:21:52 +08008925static void osd_setting_blend1_input(u32 index,
8926 struct hw_osd_blending_s *blending)
8927{
8928 struct layer_blend_s *layer_blend;
8929 u32 workaround_line = 0;
8930 /* for g12a blend shift issue */
8931
8932 if (osd_hw.hdr_used) {
8933 workaround_line = osd_hw.workaround_line;
8934 } else {
8935 if (blending->layer_cnt == 2)
8936 workaround_line = 0;
8937 else
8938 workaround_line = osd_hw.workaround_line;
8939 }
8940
8941 layer_blend = &blending->layer_blend;
8942 if (index == OSD1) {
8943 layer_blend->output_data.x =
8944 blending->dst_data.x;
8945 layer_blend->output_data.y =
8946 blending->dst_data.y
8947 + workaround_line;
8948 layer_blend->output_data.w =
8949 blending->dst_data.w;
8950 layer_blend->output_data.h =
8951 blending->dst_data.h;
8952 } else {
8953 layer_blend->output_data.x =
8954 osd_hw.free_dst_data[index].x_start;
8955 layer_blend->output_data.y =
8956 osd_hw.free_dst_data[index].y_start
8957 + workaround_line;
8958 layer_blend->output_data.w =
8959 osd_hw.free_dst_data[index].x_end -
8960 osd_hw.free_dst_data[index].x_start + 1;
8961 layer_blend->output_data.h =
8962 osd_hw.free_dst_data[index].y_end -
8963 osd_hw.free_dst_data[index].y_start + 1;
8964 }
8965 osd_log_dbg2(MODULE_BLEND,
8966 "blend1_input:input_data[osd%d]:%d,%d,%d,%d\n",
8967 index,
8968 layer_blend->output_data.x,
8969 layer_blend->output_data.y,
8970 layer_blend->output_data.w,
8971 layer_blend->output_data.h);
8972}
8973
8974/* every output is next path input */
Googler4f18c0c2022-09-20 17:23:36 +08008975static void set_blend_path(struct hw_osd_blending_s *blending)
8976{
8977 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +08008978 struct osd_blend_reg_s *osd_blend_reg;
8979 struct vpp0_blend_reg_s *vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008980 struct dispdata_s output1_data;
8981 u32 index = 0;
8982 u8 input1 = 0, input2 = 0;
8983 u32 output_index;
Googler9398cc32022-12-02 17:21:52 +08008984 s32 position_x, position_y;
Googler4f18c0c2022-09-20 17:23:36 +08008985
8986 if (!blending)
8987 return;
8988 output_index = get_output_device_id(index);
Googler9398cc32022-12-02 17:21:52 +08008989 layer_blend = &blending->layer_blend;
8990 osd_blend_reg = &blending->osd_blend_reg;
8991 vpp0_blend_reg = &blending->vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08008992 layer_blend->blend_core1_bypass = 0;
Googler9398cc32022-12-02 17:21:52 +08008993 memset(&layer_blend->input1_data, 0, sizeof(struct dispdata_s));
8994 memset(&layer_blend->input2_data, 0, sizeof(struct dispdata_s));
8995
8996 if (osd_hw.osd_preblend_en && output_index == VIU1) {
Googler9726be62022-12-14 05:53:31 +00008997 position_x = osd_hw.adjust_position_x;
Googler9398cc32022-12-02 17:21:52 +08008998 position_y = osd_hw.adjust_position_y - osd_hw.preblend_y_offset;
Googler9726be62022-12-14 05:53:31 +00008999 } else {
9000 position_x = osd_hw.disp_info[output_index].position_x;
9001 position_y = osd_hw.disp_info[output_index].position_y;
9002 }
Googler9398cc32022-12-02 17:21:52 +08009003 osd_log_dbg2(MODULE_BLEND, "osd%d:position_x/y:%d,%d;adjust_position_x/y:%d,%d\n",
9004 index,
9005 position_x,
9006 position_y,
9007 osd_hw.adjust_position_x,
9008 osd_hw.adjust_position_y);
9009
Googler4f18c0c2022-09-20 17:23:36 +08009010 switch (blending->osd_blend_mode) {
9011 case OSD_BLEND_NONE:
Googler9398cc32022-12-02 17:21:52 +08009012 vpp0_blend_reg->postbld_osd1_premult = 0;
9013 vpp0_blend_reg->postbld_src4_sel = POSTBLD_CLOSE;
9014 vpp0_blend_reg->postbld_src3_sel = POSTBLD_CLOSE;
9015 vpp0_blend_reg->postbld_osd2_premult = 0;
Googler4f18c0c2022-09-20 17:23:36 +08009016 break;
9017 case OSD_BLEND_A:
9018 /* blend0-->blend2-->sc-->vpp_osd1 or */
9019 /* sc-->blend0-->blend2-->vpp_osd1 */
9020 layer_blend->input1 = BLEND_DIN1;
Googler9398cc32022-12-02 17:21:52 +08009021 if (osd_hw.blend_bypass[OSD1])
Googler4f18c0c2022-09-20 17:23:36 +08009022 layer_blend->input1 |= BYPASS_DIN;
9023 layer_blend->input2 = BLEND_NO_DIN;
9024 index = blend_din_to_osd(BLEND_DIN1, blending);
9025 if (index >= OSD_MAX)
9026 return;
9027 if (index == OSD1) {
9028 osd_setting_blend0_input(index, blending);
Googler9398cc32022-12-02 17:21:52 +08009029 memcpy(&layer_blend->input1_data,
9030 &layer_blend->output_data,
9031 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009032 osd_setting_blend0(blending);
9033
Googler9398cc32022-12-02 17:21:52 +08009034 if (!osd_blend_reg->din0_byp_blend) {
Googler4f18c0c2022-09-20 17:23:36 +08009035 layer_blend->input1 = BLEND0_DIN;
9036 layer_blend->input2 = BLEND_NO_DIN;
9037 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +08009038 &layer_blend->output_data,
9039 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009040 /* same with blend0's background */
9041 osd_setting_blend2(blending);
9042 }
9043 /* osd1 freescale,output is vinfo.w/h */
9044 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009045 "after blend: set osd%d freescale\n",
9046 index);
Googler4f18c0c2022-09-20 17:23:36 +08009047 osd_set_freescale(index, blending);
9048
9049 layer_blend->input1 = BLEND2_DIN;
9050 layer_blend->input2 = BLEND_NO_DIN;
9051
9052 layer_blend->input1_data.x =
9053 osd_hw.free_dst_data[index].x_start +
Googler9726be62022-12-14 05:53:31 +00009054 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009055 layer_blend->input1_data.w =
9056 osd_hw.free_dst_data[index].x_end -
9057 osd_hw.free_dst_data[index].x_start + 1;
9058 layer_blend->input1_data.y =
9059 osd_hw.free_dst_data[index].y_start +
Googler9726be62022-12-14 05:53:31 +00009060 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009061 layer_blend->input1_data.h =
9062 osd_hw.free_dst_data[index].y_end -
9063 osd_hw.free_dst_data[index].y_start + 1;
9064 } else {
9065 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009066 "first: set osd%d freescale\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08009067 osd_set_freescale(index, blending);
9068 osd_hw.free_dst_data[index].x_start +=
Googler9726be62022-12-14 05:53:31 +00009069 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009070 osd_hw.free_dst_data[index].x_end +=
Googler9726be62022-12-14 05:53:31 +00009071 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009072 osd_hw.free_dst_data[index].y_start +=
Googler9726be62022-12-14 05:53:31 +00009073 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009074 osd_hw.free_dst_data[index].y_end +=
Googler9726be62022-12-14 05:53:31 +00009075 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009076
9077 osd_setting_blend0_input(index, blending);
Googler9398cc32022-12-02 17:21:52 +08009078 memcpy(&layer_blend->input1_data,
9079 &layer_blend->output_data,
9080 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009081 osd_setting_blend0(blending);
Googler9398cc32022-12-02 17:21:52 +08009082 if (!osd_blend_reg->din0_byp_blend) {
Googler4f18c0c2022-09-20 17:23:36 +08009083 layer_blend->input1 = BLEND0_DIN;
9084 layer_blend->input2 = BLEND_NO_DIN;
9085 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +08009086 &layer_blend->output_data,
9087 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009088 /* same with blend0's background */
9089 osd_setting_blend2(blending);
9090 }
9091
9092 if (index != OSD1) {
9093 /* if not osd1, need disable osd1 freescale */
9094 osd_hw.free_scale_enable[OSD1] = 0x0;
9095 osd_hw.free_scale[OSD1].h_enable = 0;
9096 osd_hw.free_scale[OSD1].v_enable = 0;
Googler9398cc32022-12-02 17:21:52 +08009097 blending->osd1_freescale_disable = 1;
Googler4f18c0c2022-09-20 17:23:36 +08009098 }
9099 /* freescale dst is != vpp input,need adjust */
9100 layer_blend->input1 = BLEND2_DIN;
9101 layer_blend->input2 = BLEND_NO_DIN;
9102
Googler9398cc32022-12-02 17:21:52 +08009103 memcpy(&layer_blend->input1_data,
9104 &layer_blend->output_data,
9105 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009106 }
9107 vpp_setting_blend(blending);
9108 break;
9109 case OSD_BLEND_AC:
9110 /* blend0 & sc-->blend1-->blend2-->sc-->vpp_osd1 */
9111 /* sc-->blend0 & blend1-->blend2-->sc-->vpp_osd1 */
9112 if (!blending->b_exchange_din) {
9113 input1 = BLEND_DIN1;
9114 input2 = BLEND_DIN4;
9115 } else {
9116 input1 = BLEND_DIN4;
9117 input2 = BLEND_DIN1;
9118 }
9119 layer_blend->input1 = input1;
9120 layer_blend->input2 = BLEND_NO_DIN;
9121 index = blend_din_to_osd(input1, blending);
9122 if (index >= OSD_MAX)
9123 return;
9124 if (index != OSD1) {
9125 /* here used freescale osd1/osd2 */
9126 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009127 "before blend0: set osd%d freescale\n",
9128 index);
Googler4f18c0c2022-09-20 17:23:36 +08009129 osd_set_freescale(index, blending);
9130 }
9131 osd_setting_blend0_input(index, blending);
Googler9398cc32022-12-02 17:21:52 +08009132 memcpy(&layer_blend->input1_data,
9133 &layer_blend->output_data,
Googler9726be62022-12-14 05:53:31 +00009134 sizeof(struct dispdata_s));
Googler9398cc32022-12-02 17:21:52 +08009135 osd_setting_blend0(blending);
9136 memcpy(&output1_data, &layer_blend->output_data,
9137 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009138
9139 index = blend_din_to_osd(input2, blending);
9140 if (index >= OSD_MAX)
9141 return;
9142 if (index != OSD1) {
9143 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009144 "before blend1: set osd%d freescale\n",
9145 index);
Googler4f18c0c2022-09-20 17:23:36 +08009146 osd_set_freescale(index, blending);
9147 }
9148 layer_blend->input1 = BLEND_NO_DIN;
9149 layer_blend->input2 = input2;
9150
9151 osd_setting_blend1_input(index, blending);
9152 memcpy(&layer_blend->input2_data,
Googler9398cc32022-12-02 17:21:52 +08009153 &layer_blend->output_data,
9154 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009155
9156 osd_setting_blend1(blending);
9157
9158 layer_blend->input1 = BLEND0_DIN;
9159 layer_blend->input2 = BLEND1_DIN;
9160 /* always used input1_data */
9161 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +08009162 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009163 osd_setting_blend2(blending);
9164
9165 /* used osd0 freescale */
9166 osd_set_freescale(OSD1, blending);
9167
9168 layer_blend->input1 = BLEND2_DIN;
9169 layer_blend->input2 = BLEND_NO_DIN;
9170 layer_blend->input1_data.x =
9171 osd_hw.free_dst_data[OSD1].x_start +
Googler9726be62022-12-14 05:53:31 +00009172 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009173 layer_blend->input1_data.w =
9174 osd_hw.free_dst_data[OSD1].x_end -
9175 osd_hw.free_dst_data[OSD1].x_start + 1;
9176 layer_blend->input1_data.y =
9177 osd_hw.free_dst_data[OSD1].y_start +
Googler9726be62022-12-14 05:53:31 +00009178 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009179 layer_blend->input1_data.h =
9180 osd_hw.free_dst_data[OSD1].y_end -
9181 osd_hw.free_dst_data[OSD1].y_start + 1;
9182 vpp_setting_blend(blending);
9183 break;
9184 case OSD_BLEND_A_C:
9185 /* blend0 -->blend2-->sc->vpp_osd1 */
9186 /* sc-->blend1 -->vpp_osd2 */
9187 /* or */
9188 /* sc-->blend0 -->blend2-->vpp_osd1 */
9189 /* sc-->blend1 -->vpp_osd2 */
9190 layer_blend->input1 = BLEND_DIN1;
Googler9398cc32022-12-02 17:21:52 +08009191 if (osd_hw.blend_bypass[OSD1])
Googler4f18c0c2022-09-20 17:23:36 +08009192 layer_blend->input1 |= BYPASS_DIN;
9193 layer_blend->input2 = BLEND_NO_DIN;
9194 index = blend_din_to_osd(BLEND_DIN1, blending);
9195 if (index >= OSD_MAX)
9196 return;
9197 osd_setting_blend0_input(index, blending);
Googler9398cc32022-12-02 17:21:52 +08009198 memcpy(&layer_blend->input1_data,
9199 &layer_blend->output_data,
9200 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009201 osd_setting_blend0(blending);
9202
Googler9398cc32022-12-02 17:21:52 +08009203 if (!osd_blend_reg->din0_byp_blend) {
Googler4f18c0c2022-09-20 17:23:36 +08009204 layer_blend->input1 = BLEND0_DIN;
9205 layer_blend->input2 = BLEND_NO_DIN;
9206 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +08009207 &layer_blend->output_data,
9208 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009209 /* background is same with blend0's background */
9210 osd_setting_blend2(blending);
9211 }
9212 /* here freescale osd0 used */
9213 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009214 "after blend: set osd%d freescale\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08009215 osd_set_freescale(index, blending);
9216 /* save freescale output */
9217 output1_data.x =
9218 osd_hw.free_dst_data[index].x_start +
Googler9726be62022-12-14 05:53:31 +00009219 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009220 output1_data.w =
9221 osd_hw.free_dst_data[index].x_end -
9222 osd_hw.free_dst_data[index].x_start + 1;
9223 output1_data.y =
9224 osd_hw.free_dst_data[index].y_start +
Googler9726be62022-12-14 05:53:31 +00009225 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009226 output1_data.h =
9227 osd_hw.free_dst_data[index].y_end -
9228 osd_hw.free_dst_data[index].y_start + 1;
9229
9230 osd_log_dbg2(MODULE_BLEND, "position_x=%d, y=%d\n",
Googler9726be62022-12-14 05:53:31 +00009231 position_x,
9232 position_y);
Googler4f18c0c2022-09-20 17:23:36 +08009233
9234 index = blend_din_to_osd(BLEND_DIN4, blending);
9235 if (index >= OSD_MAX)
9236 return;
9237 /* here freescale osd1/osd2 used */
9238 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009239 "before blend1: set osd%d freescale\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08009240 osd_set_freescale(index, blending);
9241 layer_blend->input1 = BLEND_NO_DIN;
9242 /* must bypass for shift workaround */
9243 layer_blend->input2 = BLEND_DIN4 | BYPASS_DIN;
9244 layer_blend->blend_core1_bypass = 1;
9245 osd_setting_blend1_input(index, blending);
9246 memcpy(&layer_blend->input2_data,
Googler9398cc32022-12-02 17:21:52 +08009247 &layer_blend->output_data,
9248 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009249 /* adjust offset*/
9250 layer_blend->input2_data.x +=
Googler9726be62022-12-14 05:53:31 +00009251 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009252 layer_blend->input2_data.y +=
Googler9726be62022-12-14 05:53:31 +00009253 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009254
9255 osd_setting_blend1(blending);
9256
9257 if (!blending->b_exchange_blend_in) {
9258 layer_blend->input1 = BLEND2_DIN;
9259 layer_blend->input2 = BLEND1_DIN;
9260 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +08009261 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009262 memcpy(&layer_blend->input2_data,
Googler9398cc32022-12-02 17:21:52 +08009263 &layer_blend->output_data,
9264 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009265 } else {
9266 layer_blend->input1 = BLEND1_DIN;
9267 layer_blend->input2 = BLEND2_DIN;
9268 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +08009269 &layer_blend->output_data,
9270 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009271 memcpy(&layer_blend->input2_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +08009272 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009273 }
9274 vpp_setting_blend(blending);
9275 break;
9276 case OSD_BLEND_ABC:
9277 /* blend0 -->blend2-->sc-->vpp_osd1 */
9278 /* sc-->blend1 -->blend2 */
9279 input1 = BLEND_DIN1;
9280 input2 = BLEND_DIN4;
9281 layer_blend->input1 = input1;
9282 layer_blend->input2 = BLEND_NO_DIN;
9283 index = blend_din_to_osd(input1, blending);
9284 if (index >= OSD_MAX)
9285 return;
9286 if (index != OSD1) {
9287 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009288 "index=%d, need set freescale\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08009289 osd_set_freescale(index, blending);
9290 }
9291 osd_setting_blend0_input(index, blending);
Googler9398cc32022-12-02 17:21:52 +08009292 memcpy(&layer_blend->input1_data,
9293 &layer_blend->output_data,
Googler9726be62022-12-14 05:53:31 +00009294 sizeof(struct dispdata_s));
Googler9398cc32022-12-02 17:21:52 +08009295 osd_setting_blend0(blending);
9296 memcpy(&output1_data, &layer_blend->output_data,
9297 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009298
9299 layer_blend->input1 = BLEND_DIN3;
9300 layer_blend->input2 = input2;
9301 index = blend_din_to_osd(layer_blend->input1, blending);
9302 if (index != OSD1) {
9303 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009304 "blend1 input1: set osd%d freescale\n",
9305 index);
9306 osd_set_freescale(index, blending);
9307 }
9308 osd_setting_blend1_input(index, blending);
9309 memcpy(&layer_blend->input1_data,
9310 &layer_blend->output_data,
9311 sizeof(struct dispdata_s));
9312
9313 index = blend_din_to_osd(layer_blend->input2, blending);
9314 if (index >= OSD_MAX)
9315 return;
9316 if (index != OSD1) {
9317 osd_log_dbg2(MODULE_BLEND,
9318 "blend1 input2: set osd%d freescale\n",
9319 index);
9320 osd_set_freescale(index, blending);
9321 }
9322 osd_setting_blend1_input(index, blending);
9323 memcpy(&layer_blend->input2_data,
9324 &layer_blend->output_data,
9325 sizeof(struct dispdata_s));
9326 osd_setting_blend1(blending);
9327
9328 layer_blend->input1 = BLEND0_DIN;
9329 layer_blend->input2 = BLEND1_DIN;
9330 memcpy(&layer_blend->input1_data, &output1_data,
9331 sizeof(struct dispdata_s));
9332 memcpy(&layer_blend->input2_data, &layer_blend->output_data,
9333 sizeof(struct dispdata_s));
9334 osd_setting_blend2(blending);
9335 /* used osd0 freescale */
9336 osd_set_freescale(OSD1, blending);
9337
9338 layer_blend->input1 = BLEND2_DIN;
9339 layer_blend->input2 = BLEND_NO_DIN;
9340 layer_blend->input1_data.x =
9341 osd_hw.free_dst_data[OSD1].x_start +
9342 position_x;
9343 layer_blend->input1_data.w =
9344 osd_hw.free_dst_data[OSD1].x_end -
9345 osd_hw.free_dst_data[OSD1].x_start + 1;
9346 layer_blend->input1_data.y =
9347 osd_hw.free_dst_data[OSD1].y_start +
9348 position_y;
9349 layer_blend->input1_data.h =
9350 osd_hw.free_dst_data[OSD1].y_end -
9351 osd_hw.free_dst_data[OSD1].y_start + 1;
9352 vpp_setting_blend(blending);
9353 break;
9354 case OSD_BLEND_A_BC:
9355 /* blend0 -->blend2-->sc->vpp_osd1 */
9356 /* 2input-->sc-->blend1 -->vpp_osd2 */
9357 layer_blend->input1 = BLEND_DIN1;
9358 if (osd_hw.blend_bypass[OSD1])
9359 layer_blend->input1 |= BYPASS_DIN;
9360 layer_blend->input2 = BLEND_NO_DIN;
9361 index = blend_din_to_osd(BLEND_DIN1, blending);
9362 if (index >= OSD_MAX)
9363 return;
9364 osd_setting_blend0_input(index, blending);
9365 osd_setting_blend0(blending);
9366
9367 if (!osd_blend_reg->din0_byp_blend) {
9368 layer_blend->input1 = BLEND0_DIN;
9369 layer_blend->input2 = BLEND_NO_DIN;
9370 memcpy(&layer_blend->input1_data,
9371 &layer_blend->output_data,
9372 sizeof(struct dispdata_s));
9373 /* background is same with blend0's background */
9374 osd_setting_blend2(blending);
9375 }
9376
9377 osd_log_dbg(MODULE_BLEND,
9378 "after blend2: set osd%d freescale\n", index);
9379 osd_set_freescale(index, blending);
9380 /* save freescale output */
9381 output1_data.x =
9382 osd_hw.free_dst_data[index].x_start +
9383 position_x;
9384 output1_data.w =
9385 osd_hw.free_dst_data[index].x_end -
9386 osd_hw.free_dst_data[index].x_start + 1;
9387 output1_data.y =
9388 osd_hw.free_dst_data[index].y_start +
9389 position_y;
9390 output1_data.h =
9391 osd_hw.free_dst_data[index].y_end -
9392 osd_hw.free_dst_data[index].y_start + 1;
9393 index = blend_din_to_osd(BLEND_DIN3, blending);
9394 if (index >= OSD_MAX)
9395 return;
9396 osd_log_dbg2(MODULE_BLEND,
9397 "before blend1: set osd%d freescale\n", index);
9398 osd_set_freescale(index, blending);
9399 layer_blend->input1_data.x =
9400 osd_hw.free_dst_data[index].x_start +
9401 position_x;
9402 layer_blend->input1_data.w =
9403 osd_hw.free_dst_data[index].x_end -
9404 osd_hw.free_dst_data[index].x_start + 1;
9405 layer_blend->input1_data.y =
9406 osd_hw.free_dst_data[index].y_start +
9407 position_y;
9408 layer_blend->input1_data.h =
9409 osd_hw.free_dst_data[index].y_end -
9410 osd_hw.free_dst_data[index].y_start + 1;
9411
9412 index = blend_din_to_osd(BLEND_DIN4, blending);
9413 if (index >= OSD_MAX)
9414 return;
9415 osd_log_dbg2(MODULE_BLEND,
9416 "before blend1: set osd%d freescale\n", index);
9417 osd_set_freescale(index, blending);
9418 layer_blend->input2_data.x =
9419 osd_hw.free_dst_data[index].x_start +
9420 position_x;
9421 layer_blend->input2_data.w =
9422 osd_hw.free_dst_data[index].x_end -
9423 osd_hw.free_dst_data[index].x_start + 1;
9424 layer_blend->input2_data.y =
9425 osd_hw.free_dst_data[index].y_start +
9426 position_y;
9427 layer_blend->input2_data.h =
9428 osd_hw.free_dst_data[index].y_end -
9429 osd_hw.free_dst_data[index].y_start + 1;
9430
9431 /* always route(bypass) to dout1 */
9432 layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN;
9433 layer_blend->input2 = BLEND_DIN4;
9434
9435 osd_setting_blend1(blending);
9436
9437 if (!blending->b_exchange_blend_in) {
9438 layer_blend->input1 = BLEND2_DIN;
9439 layer_blend->input2 = BLEND1_DIN;
9440 memcpy(&layer_blend->input1_data, &output1_data,
9441 sizeof(struct dispdata_s));
9442 memcpy(&layer_blend->input2_data,
9443 &layer_blend->output_data,
9444 sizeof(struct dispdata_s));
9445 } else {
9446 layer_blend->input1 = BLEND1_DIN;
9447 layer_blend->input2 = BLEND2_DIN;
9448 memcpy(&layer_blend->input1_data,
9449 &layer_blend->output_data,
9450 sizeof(struct dispdata_s));
9451 memcpy(&layer_blend->input2_data,
9452 &output1_data,
9453 sizeof(struct dispdata_s));
9454 }
9455 vpp_setting_blend(blending);
9456 break;
9457 case OSD_BLEND_AB_C:
9458 /* blend0 -->blend2-->sc->vpp_osd1 */
9459 /* sc-->blend1-->blend2-->sc-->vpp_osd1 */
9460 /* sc -->vpp_osd2 */
9461 layer_blend->input1 = BLEND_DIN1;
9462 layer_blend->input2 = BLEND_NO_DIN;
9463 blending->blend_din = BLEND_DIN1;
9464 index = blend_din_to_osd(BLEND_DIN1, blending);
9465 if (index != OSD1) {
9466 osd_log_info("index=%d, need set freescale\n", index);
9467 osd_set_freescale(index, blending);
9468 }
9469 osd_setting_blend0_input(index, blending);
9470 memcpy(&layer_blend->input1_data,
9471 &layer_blend->output_data,
9472 sizeof(struct dispdata_s));
9473 osd_setting_blend0(blending);
9474 /* save blend0 output */
9475 memcpy(&output1_data, &layer_blend->output_data,
9476 sizeof(struct dispdata_s));
9477
9478 /* din3 input to blend1 */
9479 layer_blend->input1 = BLEND_DIN3;
9480 layer_blend->input2 = BLEND_NO_DIN | BYPASS_DIN;
9481 layer_blend->blend_core1_bypass = 1;
9482 blending->blend_din = BLEND_DIN3;
9483 index = blend_din_to_osd(BLEND_DIN3, blending);
9484 if (index != OSD1) {
9485 osd_log_dbg2(MODULE_BLEND,
9486 "before blend1: set osd%d freescale\n",
9487 index);
9488 osd_set_freescale(index, blending);
9489 }
9490 osd_setting_blend1_input(index, blending);
9491 memcpy(&layer_blend->input1_data,
9492 &layer_blend->output_data,
9493 sizeof(struct dispdata_s));
9494 osd_setting_blend1(blending);
9495
9496 /* din1=>blend0 & din3-> blend1 ==> blend2 */
9497 layer_blend->input1 = BLEND0_DIN;
9498 layer_blend->input2 = BLEND1_DIN;
9499 memcpy(&layer_blend->input1_data, &output1_data,
9500 sizeof(struct dispdata_s));
9501 memcpy(&layer_blend->input2_data, &layer_blend->output_data,
9502 sizeof(struct dispdata_s));
9503 osd_setting_blend2(blending);
9504
9505 /* blend2 ==> osd0 freescale */
9506 osd_set_freescale(OSD1, blending);
9507 output1_data.x =
9508 osd_hw.free_dst_data[OSD1].x_start +
9509 position_x;
9510 output1_data.w =
9511 osd_hw.free_dst_data[OSD1].x_end -
9512 osd_hw.free_dst_data[OSD1].x_start + 1;
9513 output1_data.y =
9514 osd_hw.free_dst_data[OSD1].y_start +
9515 position_y;
9516 output1_data.h =
9517 osd_hw.free_dst_data[OSD1].y_end -
9518 osd_hw.free_dst_data[OSD1].y_start + 1;
9519 osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n",
9520 output1_data.x,
9521 output1_data.w,
9522 output1_data.y,
9523 output1_data.h);
9524
9525 /* din4 ==> vpp */
9526 index = blend_din_to_osd(BLEND_DIN4, blending);
9527 blending->blend_din = BLEND_DIN4;
9528 osd_log_dbg2(MODULE_BLEND,
9529 "bypass blend1: set osd%d freescale\n", index);
9530 osd_set_freescale(index, blending);
9531
9532 layer_blend->input2_data.x =
9533 osd_hw.free_dst_data[index].x_start +
9534 position_x;
9535 layer_blend->input2_data.w =
9536 osd_hw.free_dst_data[index].x_end -
9537 osd_hw.free_dst_data[index].x_start + 1;
9538 layer_blend->input2_data.y =
9539 osd_hw.free_dst_data[index].y_start +
9540 position_y;
9541 layer_blend->input2_data.h =
9542 osd_hw.free_dst_data[index].y_end -
9543 osd_hw.free_dst_data[index].y_start + 1;
9544
9545 /* 2vpp input */
9546 if (!blending->b_exchange_blend_in) {
9547 layer_blend->input1 = BLEND2_DIN;
9548 layer_blend->input2 = BLEND1_DIN;
9549 memcpy(&layer_blend->input1_data, &output1_data,
9550 sizeof(struct dispdata_s));
9551 } else {
9552 layer_blend->input1 = BLEND1_DIN;
9553 layer_blend->input2 = BLEND2_DIN;
9554 memcpy(&layer_blend->input1_data,
9555 &layer_blend->input2_data,
9556 sizeof(struct dispdata_s));
9557 memcpy(&layer_blend->input2_data,
9558 &output1_data,
9559 sizeof(struct dispdata_s));
9560 }
9561 vpp_setting_blend(blending);
9562 break;
9563 case OSD_BLEND_ABCD:
9564 /* blend0 -->blend2-->sc-->vpp_osd1 */
9565 /* sc-->blend1 -->blend2 */
9566 layer_blend->input1 = BLEND_DIN1;
9567 layer_blend->input2 = BLEND_DIN2;
9568 blending->blend_din = BLEND_DIN1;
9569 index = blend_din_to_osd(layer_blend->input1, blending);
9570 if (index != OSD1) {
9571 osd_log_dbg2(MODULE_BLEND,
9572 "index=%d, need set freescale\n", index);
9573 osd_set_freescale(index, blending);
9574 }
9575 osd_setting_blend0_input(index, blending);
9576 memcpy(&layer_blend->input1_data,
9577 &layer_blend->output_data,
9578 sizeof(struct dispdata_s));
9579
9580 blending->blend_din = BLEND_DIN2;
9581 index = blend_din_to_osd(layer_blend->input2, blending);
9582 if (index != OSD1) {
9583 osd_log_dbg2(MODULE_BLEND,
9584 "index=%d, need set freescale\n", index);
9585 osd_set_freescale(index, blending);
9586 }
9587 osd_setting_blend0_input(index, blending);
9588 memcpy(&layer_blend->input2_data,
9589 &layer_blend->output_data,
9590 sizeof(struct dispdata_s));
9591 osd_setting_blend0(blending);
9592
9593 memcpy(&output1_data, &layer_blend->output_data,
9594 sizeof(struct dispdata_s));
9595
9596 layer_blend->input1 = BLEND_DIN3;
9597 layer_blend->input2 = BLEND_DIN4;
9598 index = blend_din_to_osd(layer_blend->input1, blending);
9599 if (index != OSD1) {
9600 osd_log_dbg2(MODULE_BLEND,
Googler9726be62022-12-14 05:53:31 +00009601 "blend1 input1: set osd%d freescale\n",
9602 index);
Googler4f18c0c2022-09-20 17:23:36 +08009603 osd_set_freescale(index, blending);
9604 }
9605 osd_setting_blend1_input(index, blending);
9606 memcpy(&layer_blend->input1_data,
Googler9726be62022-12-14 05:53:31 +00009607 &layer_blend->output_data,
9608 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009609
9610 index = blend_din_to_osd(layer_blend->input2, blending);
9611 if (index >= OSD_MAX)
9612 return;
9613 if (index != OSD1) {
9614 osd_log_dbg2(MODULE_BLEND,
Googler9726be62022-12-14 05:53:31 +00009615 "blend1 input2: set osd%d freescale\n",
9616 index);
Googler4f18c0c2022-09-20 17:23:36 +08009617 osd_set_freescale(index, blending);
9618 }
9619 osd_setting_blend1_input(index, blending);
9620 memcpy(&layer_blend->input2_data,
Googler9726be62022-12-14 05:53:31 +00009621 &layer_blend->output_data,
9622 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009623 osd_setting_blend1(blending);
9624
9625 layer_blend->input1 = BLEND0_DIN;
9626 layer_blend->input2 = BLEND1_DIN;
9627 memcpy(&layer_blend->input1_data, &output1_data,
Googler9726be62022-12-14 05:53:31 +00009628 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009629 memcpy(&layer_blend->input2_data, &layer_blend->output_data,
Googler9726be62022-12-14 05:53:31 +00009630 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009631 osd_setting_blend2(blending);
9632 /* used osd0 freescale */
9633 osd_set_freescale(OSD1, blending);
9634
9635 layer_blend->input1 = BLEND2_DIN;
9636 layer_blend->input2 = BLEND_NO_DIN;
9637 layer_blend->input1_data.x =
9638 osd_hw.free_dst_data[OSD1].x_start +
Googler9726be62022-12-14 05:53:31 +00009639 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009640 layer_blend->input1_data.w =
9641 osd_hw.free_dst_data[OSD1].x_end -
9642 osd_hw.free_dst_data[OSD1].x_start + 1;
9643 layer_blend->input1_data.y =
9644 osd_hw.free_dst_data[OSD1].y_start +
Googler9726be62022-12-14 05:53:31 +00009645 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009646 layer_blend->input1_data.h =
9647 osd_hw.free_dst_data[OSD1].y_end -
9648 osd_hw.free_dst_data[OSD1].y_start + 1;
9649 vpp_setting_blend(blending);
9650 break;
Googler9398cc32022-12-02 17:21:52 +08009651 case OSD_BLEND_AB_CD:
9652 /* blend0 -->blend2-->sc-->vpp_osd1 */
9653 /* sc-->blend1 -->blend2 */
Googler4f18c0c2022-09-20 17:23:36 +08009654 layer_blend->input1 = BLEND_DIN1;
Googler9398cc32022-12-02 17:21:52 +08009655 layer_blend->input2 = BLEND_DIN2;
9656 blending->blend_din = BLEND_DIN1;
9657 index = blend_din_to_osd(layer_blend->input1, blending);
9658 if (index != OSD1) {
9659 osd_log_dbg2(MODULE_BLEND,
9660 "index=%d, need set freescale\n", index);
9661 osd_set_freescale(index, blending);
9662 }
Googler4f18c0c2022-09-20 17:23:36 +08009663 osd_setting_blend0_input(index, blending);
Googler9398cc32022-12-02 17:21:52 +08009664 memcpy(&layer_blend->input1_data,
9665 &layer_blend->output_data,
9666 sizeof(struct dispdata_s));
9667 blending->blend_din = BLEND_DIN2;
9668 index = blend_din_to_osd(layer_blend->input2, blending);
9669 if (index != OSD1) {
9670 osd_log_dbg2(MODULE_BLEND,
9671 "index=%d, need set freescale\n", index);
9672 osd_set_freescale(index, blending);
9673 }
9674 osd_setting_blend0_input(index, blending);
9675 memcpy(&layer_blend->input2_data,
9676 &layer_blend->output_data,
9677 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009678 osd_setting_blend0(blending);
9679
Googler9398cc32022-12-02 17:21:52 +08009680 if (!osd_blend_reg->din0_byp_blend) {
Googler4f18c0c2022-09-20 17:23:36 +08009681 layer_blend->input1 = BLEND0_DIN;
9682 layer_blend->input2 = BLEND_NO_DIN;
9683 memcpy(&layer_blend->input1_data,
Googler9726be62022-12-14 05:53:31 +00009684 &layer_blend->output_data,
9685 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009686 /* background is same with blend0's background */
9687 osd_setting_blend2(blending);
9688 }
9689
Googler9398cc32022-12-02 17:21:52 +08009690 osd_log_dbg2(MODULE_BLEND,
9691 "after blend2: set osd%d freescale\n", OSD1);
9692 osd_set_freescale(OSD1, blending);
Googler4f18c0c2022-09-20 17:23:36 +08009693 /* save freescale output */
9694 output1_data.x =
Googler9398cc32022-12-02 17:21:52 +08009695 osd_hw.free_dst_data[OSD1].x_start +
Googler9726be62022-12-14 05:53:31 +00009696 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009697 output1_data.w =
Googler9398cc32022-12-02 17:21:52 +08009698 osd_hw.free_dst_data[OSD1].x_end -
9699 osd_hw.free_dst_data[OSD1].x_start + 1;
Googler4f18c0c2022-09-20 17:23:36 +08009700 output1_data.y =
Googler9398cc32022-12-02 17:21:52 +08009701 osd_hw.free_dst_data[OSD1].y_start +
Googler9726be62022-12-14 05:53:31 +00009702 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009703 output1_data.h =
Googler9398cc32022-12-02 17:21:52 +08009704 osd_hw.free_dst_data[OSD1].y_end -
9705 osd_hw.free_dst_data[OSD1].y_start + 1;
9706
Googler4f18c0c2022-09-20 17:23:36 +08009707 index = blend_din_to_osd(BLEND_DIN3, blending);
9708 if (index >= OSD_MAX)
9709 return;
9710 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009711 "before blend1: set osd%d freescale\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08009712 osd_set_freescale(index, blending);
9713 layer_blend->input1_data.x =
9714 osd_hw.free_dst_data[index].x_start +
Googler9726be62022-12-14 05:53:31 +00009715 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009716 layer_blend->input1_data.w =
9717 osd_hw.free_dst_data[index].x_end -
9718 osd_hw.free_dst_data[index].x_start + 1;
9719 layer_blend->input1_data.y =
9720 osd_hw.free_dst_data[index].y_start +
Googler9726be62022-12-14 05:53:31 +00009721 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009722 layer_blend->input1_data.h =
9723 osd_hw.free_dst_data[index].y_end -
9724 osd_hw.free_dst_data[index].y_start + 1;
9725
9726 index = blend_din_to_osd(BLEND_DIN4, blending);
9727 if (index >= OSD_MAX)
9728 return;
9729 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009730 "before blend1: set osd%d freescale\n", index);
Googler4f18c0c2022-09-20 17:23:36 +08009731 osd_set_freescale(index, blending);
9732 layer_blend->input2_data.x =
9733 osd_hw.free_dst_data[index].x_start +
Googler9726be62022-12-14 05:53:31 +00009734 position_x;
Googler4f18c0c2022-09-20 17:23:36 +08009735 layer_blend->input2_data.w =
9736 osd_hw.free_dst_data[index].x_end -
9737 osd_hw.free_dst_data[index].x_start + 1;
9738 layer_blend->input2_data.y =
9739 osd_hw.free_dst_data[index].y_start +
Googler9726be62022-12-14 05:53:31 +00009740 position_y;
Googler4f18c0c2022-09-20 17:23:36 +08009741 layer_blend->input2_data.h =
9742 osd_hw.free_dst_data[index].y_end -
9743 osd_hw.free_dst_data[index].y_start + 1;
9744
9745 /* always route(bypass) to dout1 */
9746 layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN;
9747 layer_blend->input2 = BLEND_DIN4;
9748
9749 osd_setting_blend1(blending);
9750
9751 if (!blending->b_exchange_blend_in) {
9752 layer_blend->input1 = BLEND2_DIN;
9753 layer_blend->input2 = BLEND1_DIN;
9754 memcpy(&layer_blend->input1_data, &output1_data,
Googler9726be62022-12-14 05:53:31 +00009755 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009756 memcpy(&layer_blend->input2_data,
Googler9726be62022-12-14 05:53:31 +00009757 &layer_blend->output_data,
9758 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009759 } else {
9760 layer_blend->input1 = BLEND1_DIN;
9761 layer_blend->input2 = BLEND2_DIN;
9762 memcpy(&layer_blend->input1_data,
Googler9726be62022-12-14 05:53:31 +00009763 &layer_blend->output_data,
9764 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009765 memcpy(&layer_blend->input2_data,
Googler9726be62022-12-14 05:53:31 +00009766 &output1_data,
9767 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +08009768 }
9769 vpp_setting_blend(blending);
9770 break;
Googler4f18c0c2022-09-20 17:23:36 +08009771 }
9772}
9773
9774static void osd_setting_blend0_new(struct hw_osd_blending_s *blending)
9775{
Googler9398cc32022-12-02 17:21:52 +08009776 struct osd_blend_reg_s *osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08009777 struct layer_blend_s *layer_blend;
9778 u32 index = 0;
9779 u32 bld_osd_h_start = 0, bld_osd_h_end = 0;
9780 u32 bld_osd_v_start = 0, bld_osd_v_end = 0;
Googler9398cc32022-12-02 17:21:52 +08009781 u32 blend_hsize, blend_vsize;
Googler4f18c0c2022-09-20 17:23:36 +08009782
9783 if (!blending)
9784 return;
Googler9398cc32022-12-02 17:21:52 +08009785 layer_blend = &blending->layer_blend;
9786 osd_blend_reg = &blending->osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +08009787 /* blend0 only accept input1 */
9788 if (layer_blend->input1 & BYPASS_DIN) {
Googler9398cc32022-12-02 17:21:52 +08009789 osd_blend_reg->din0_byp_blend = 1;
Googler4f18c0c2022-09-20 17:23:36 +08009790 layer_blend->input1 &= ~BYPASS_DIN;
Googler9398cc32022-12-02 17:21:52 +08009791 } else {
9792 osd_blend_reg->din0_byp_blend = 0;
Googler4f18c0c2022-09-20 17:23:36 +08009793 }
Googler38bda472022-08-19 10:07:08 -07009794 if (layer_blend->input1 != BLEND_NO_DIN) {
Googler9398cc32022-12-02 17:21:52 +08009795 /* calculate osd blend din scope */
Googler38bda472022-08-19 10:07:08 -07009796 index = blend_din_to_osd(layer_blend->input1, blending);
9797 if (index >= OSD_MAX)
9798 return;
9799 layer_blend->input1_data.x =
9800 osd_hw.free_dst_data[index].x_start;
9801 layer_blend->input1_data.y =
9802 osd_hw.free_dst_data[index].y_start;
9803 layer_blend->input1_data.w =
9804 osd_hw.free_dst_data[index].x_end -
9805 osd_hw.free_dst_data[index].x_start + 1;
9806 layer_blend->input1_data.h =
9807 osd_hw.free_dst_data[index].y_end -
9808 osd_hw.free_dst_data[index].y_start + 1;
9809
Googler38bda472022-08-19 10:07:08 -07009810 bld_osd_h_start =
9811 layer_blend->input1_data.x;
9812 bld_osd_h_end =
9813 layer_blend->input1_data.x +
9814 layer_blend->input1_data.w - 1;
9815 bld_osd_v_start =
9816 layer_blend->input1_data.y;
9817 bld_osd_v_end =
9818 layer_blend->input1_data.y +
9819 layer_blend->input1_data.h - 1;
Googler9398cc32022-12-02 17:21:52 +08009820 osd_blend_reg->osd_blend_din_scope_h[index] =
Googler38bda472022-08-19 10:07:08 -07009821 bld_osd_h_end << 16 | bld_osd_h_start;
Googler9398cc32022-12-02 17:21:52 +08009822 osd_blend_reg->osd_blend_din_scope_v[index] =
Googler38bda472022-08-19 10:07:08 -07009823 bld_osd_v_end << 16 | bld_osd_v_start;
9824 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009825 "blend0:input1_data[osd%d]:%d,%d,%d,%d\n",
9826 index,
9827 layer_blend->input1_data.x,
9828 layer_blend->input1_data.y,
9829 layer_blend->input1_data.w,
9830 layer_blend->input1_data.h);
Googler38bda472022-08-19 10:07:08 -07009831 }
9832 if (layer_blend->input2 != BLEND_NO_DIN) {
9833 index = blend_din_to_osd(layer_blend->input2, blending);
9834 if (index >= OSD_MAX)
9835 return;
9836 layer_blend->input2_data.x =
9837 osd_hw.free_dst_data[index].x_start;
9838 layer_blend->input2_data.y =
9839 osd_hw.free_dst_data[index].y_start;
9840 layer_blend->input2_data.w =
9841 osd_hw.free_dst_data[index].x_end -
9842 osd_hw.free_dst_data[index].x_start + 1;
9843 layer_blend->input2_data.h =
9844 osd_hw.free_dst_data[index].y_end -
9845 osd_hw.free_dst_data[index].y_start + 1;
9846 /* calculate osd blend din scope */
9847 bld_osd_h_start =
9848 layer_blend->input2_data.x;
9849 bld_osd_h_end =
9850 layer_blend->input2_data.x +
9851 layer_blend->input2_data.w - 1;
9852 bld_osd_v_start =
9853 layer_blend->input2_data.y;
9854 bld_osd_v_end =
9855 layer_blend->input2_data.y +
9856 layer_blend->input2_data.h - 1;
Googler9398cc32022-12-02 17:21:52 +08009857 osd_blend_reg->osd_blend_din_scope_h[index] =
Googler38bda472022-08-19 10:07:08 -07009858 bld_osd_h_end << 16 | bld_osd_h_start;
Googler9398cc32022-12-02 17:21:52 +08009859 osd_blend_reg->osd_blend_din_scope_v[index] =
Googler38bda472022-08-19 10:07:08 -07009860 bld_osd_v_end << 16 | bld_osd_v_start;
9861 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +08009862 "blend0:input2_data[osd%d]:%d,%d,%d,%d\n",
9863 index,
9864 layer_blend->input2_data.x,
9865 layer_blend->input2_data.y,
9866 layer_blend->input2_data.w,
9867 layer_blend->input2_data.h);
Googler38bda472022-08-19 10:07:08 -07009868 }
Googler9398cc32022-12-02 17:21:52 +08009869
9870 if (osd_blend_reg->din0_byp_blend || layer_blend->input1 == BLEND_NO_DIN) {
Googler38bda472022-08-19 10:07:08 -07009871 /* blend din3 bypass,output == input */
Googler9398cc32022-12-02 17:21:52 +08009872 if (layer_blend->input2 == BLEND_NO_DIN)
Googler38bda472022-08-19 10:07:08 -07009873 memcpy(&layer_blend->output_data,
Googler9726be62022-12-14 05:53:31 +00009874 &layer_blend->input1_data,
9875 sizeof(struct dispdata_s));
Googler9398cc32022-12-02 17:21:52 +08009876 else
Googler38bda472022-08-19 10:07:08 -07009877 memcpy(&layer_blend->output_data,
Googler9726be62022-12-14 05:53:31 +00009878 &layer_blend->input2_data,
9879 sizeof(struct dispdata_s));
Googler9398cc32022-12-02 17:21:52 +08009880 } else {
Googler38bda472022-08-19 10:07:08 -07009881 calc_max_output(blending);
Googler9398cc32022-12-02 17:21:52 +08009882 }
Googler38bda472022-08-19 10:07:08 -07009883 blend_hsize = layer_blend->output_data.w;
9884 blend_vsize = layer_blend->output_data.h;
Googler9398cc32022-12-02 17:21:52 +08009885 osd_blend_reg->osd_blend_blend0_size =
9886 blend_vsize << 16 | blend_hsize;
9887
9888 osd_log_dbg2(MODULE_BLEND,
9889 "blend0:layer_blend->output_data:%d,%d,%d,%d\n",
9890 layer_blend->output_data.x,
9891 layer_blend->output_data.y,
9892 layer_blend->output_data.w,
9893 layer_blend->output_data.h);
9894}
9895
9896static void osd_setting_blend1_new(struct hw_osd_blending_s *blending)
9897{
9898 struct layer_blend_s *layer_blend;
9899 struct osd_blend_reg_s *osd_blend_reg;
9900 u32 index = 0;
9901 u32 blend_hsize, blend_vsize;
9902 u32 bld_osd_h_start = 0, bld_osd_h_end = 0;
9903 u32 bld_osd_v_start = 0, bld_osd_v_end = 0;
9904 /* for g12a blend shift issue */
9905
9906 if (!blending)
9907 return;
9908 layer_blend = &blending->layer_blend;
9909 osd_blend_reg = &blending->osd_blend_reg;
9910 if (layer_blend->input1 & BYPASS_DIN) {
9911 /* blend1_din2 bypass to dout1 */
9912 osd_blend_reg->din2_osd_sel = 1;
9913 layer_blend->input1 &= ~BYPASS_DIN;
9914 } else {
9915 /* blend1_dout to blend2 */
9916 osd_blend_reg->din2_osd_sel = 0;
9917 }
9918 if (layer_blend->input2 & BYPASS_DIN) {
9919 /* blend1_din3 bypass to dout1 */
9920 osd_blend_reg->din3_osd_sel = 1;
9921 layer_blend->input2 &= ~BYPASS_DIN;
9922 } else {
9923 /* blend1_din3 input to blend1 */
9924 osd_blend_reg->din3_osd_sel = 0;
9925 }
9926 if (layer_blend->input1 != BLEND_NO_DIN) {
9927 index = blend_din_to_osd(layer_blend->input1, blending);
9928 if (index >= OSD_MAX)
9929 return;
9930 layer_blend->input1_data.x =
9931 osd_hw.free_dst_data[index].x_start;
9932 layer_blend->input1_data.y =
9933 osd_hw.free_dst_data[index].y_start;
9934 layer_blend->input1_data.w =
9935 osd_hw.free_dst_data[index].x_end -
9936 osd_hw.free_dst_data[index].x_start + 1;
9937 layer_blend->input1_data.h =
9938 osd_hw.free_dst_data[index].y_end -
9939 osd_hw.free_dst_data[index].y_start + 1;
9940
9941 /* calculate osd blend din scope */
9942 bld_osd_h_start =
9943 layer_blend->input1_data.x;
9944 bld_osd_h_end =
9945 layer_blend->input1_data.x +
9946 layer_blend->input1_data.w - 1;
9947 bld_osd_v_start =
9948 layer_blend->input1_data.y;
9949 bld_osd_v_end =
9950 layer_blend->input1_data.y +
9951 layer_blend->input1_data.h - 1;
9952 osd_blend_reg->osd_blend_din_scope_h[index] =
9953 bld_osd_h_end << 16 | bld_osd_h_start;
9954 osd_blend_reg->osd_blend_din_scope_v[index] =
9955 bld_osd_v_end << 16 | bld_osd_v_start;
9956 osd_log_dbg2(MODULE_BLEND,
9957 "blend1:input1_data(osd%d):%d,%d,%d,%d\n",
9958 index,
9959 layer_blend->input1_data.x,
9960 layer_blend->input1_data.y,
9961 layer_blend->input1_data.w,
9962 layer_blend->input1_data.h);
9963 }
9964 if (layer_blend->input2 != BLEND_NO_DIN) {
9965 index = blend_din_to_osd(layer_blend->input2, blending);
9966 if (index >= OSD_MAX)
9967 return;
9968 layer_blend->input2_data.x =
9969 osd_hw.free_dst_data[index].x_start;
9970 layer_blend->input2_data.y =
9971 osd_hw.free_dst_data[index].y_start;
9972 layer_blend->input2_data.w =
9973 osd_hw.free_dst_data[index].x_end -
9974 osd_hw.free_dst_data[index].x_start + 1;
9975 layer_blend->input2_data.h =
9976 osd_hw.free_dst_data[index].y_end -
9977 osd_hw.free_dst_data[index].y_start + 1;
9978 /* calculate osd blend din scope */
9979 bld_osd_h_start =
9980 layer_blend->input2_data.x;
9981 bld_osd_h_end =
9982 layer_blend->input2_data.x +
9983 layer_blend->input2_data.w - 1;
9984 bld_osd_v_start =
9985 layer_blend->input2_data.y;
9986 bld_osd_v_end =
9987 layer_blend->input2_data.y +
9988 layer_blend->input2_data.h - 1;
9989 osd_blend_reg->osd_blend_din_scope_h[index] =
9990 bld_osd_h_end << 16 | bld_osd_h_start;
9991 osd_blend_reg->osd_blend_din_scope_v[index] =
9992 bld_osd_v_end << 16 | bld_osd_v_start;
9993 osd_log_dbg2(MODULE_BLEND,
9994 "layer_blend1:input2_data:%d,%d,%d,%d\n",
9995 layer_blend->input2_data.x,
9996 layer_blend->input2_data.y,
9997 layer_blend->input2_data.w,
9998 layer_blend->input2_data.h);
9999 }
10000 if (osd_blend_reg->din3_osd_sel || layer_blend->input1 == BLEND_NO_DIN) {
10001 /* blend din3 bypass,output == input */
10002 if (layer_blend->input2 == BLEND_NO_DIN) {
10003 memcpy(&layer_blend->output_data,
10004 &layer_blend->input1_data,
10005 sizeof(struct dispdata_s));
10006 } else {
10007 memcpy(&layer_blend->output_data,
10008 &layer_blend->input2_data,
10009 sizeof(struct dispdata_s));
10010 }
10011 } else {
10012 calc_max_output(blending);
10013 }
10014 blend_hsize = layer_blend->output_data.w;
10015 blend_vsize = layer_blend->output_data.h;
10016 osd_blend_reg->osd_blend_blend1_size =
Googler4f18c0c2022-09-20 17:23:36 +080010017 blend_vsize << 16 | blend_hsize;
10018
10019 osd_log_dbg2(MODULE_BLEND, "layer_blend1->output_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +080010020 layer_blend->output_data.x,
10021 layer_blend->output_data.y,
10022 layer_blend->output_data.w,
10023 layer_blend->output_data.h);
Googler4f18c0c2022-09-20 17:23:36 +080010024}
10025
10026/* input w, h is background */
10027static void osd_set_freescale_new(u32 index,
Googler9398cc32022-12-02 17:21:52 +080010028 struct hw_osd_blending_s *blending)
Googler4f18c0c2022-09-20 17:23:36 +080010029
10030{
10031 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +080010032 struct osd_blend_reg_s *osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +080010033 u32 width, height;
10034 u32 src_height;
10035 u32 output_index;
10036
Googler9398cc32022-12-02 17:21:52 +080010037 layer_blend = &blending->layer_blend;
10038 osd_blend_reg = &blending->osd_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +080010039 if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
10040 osd_log_err("error osd index=%d\n", index);
10041 return;
10042 }
10043 output_index = get_output_device_id(index);
Googler9726be62022-12-14 05:53:31 +000010044
10045 if (!(osd_hw.osd_display_debug[output_index] &&
Googler9398cc32022-12-02 17:21:52 +080010046 !osd_hw.free_scale_enable[index])) {
Googler9726be62022-12-14 05:53:31 +000010047 osd_hw.free_scale_enable[index] = 0x10001;
10048 osd_hw.free_scale[index].h_enable = 1;
10049 osd_hw.free_scale[index].v_enable = 1;
10050 osd_hw.free_scale_mode[index] = 1;
10051 }
Googler4f18c0c2022-09-20 17:23:36 +080010052
10053 osd_hw.free_src_data[index].x_start =
10054 osd_hw.src_data[index].x;
10055 osd_hw.free_src_data[index].x_end =
10056 osd_hw.src_data[index].x +
10057 osd_hw.src_data[index].w - 1;
10058 osd_hw.free_src_data[index].y_start =
10059 osd_hw.src_data[index].y;
10060 osd_hw.free_src_data[index].y_end =
10061 osd_hw.src_data[index].y +
10062 osd_hw.src_data[index].h - 1;
10063
10064 /* direct used dst as freescale dst */
10065 osd_hw.free_dst_data[index].x_start =
10066 osd_hw.dst_data[index].x;
10067 osd_hw.free_dst_data[index].y_start =
10068 osd_hw.dst_data[index].y;
10069 width = osd_hw.dst_data[index].w;
10070 height = osd_hw.dst_data[index].h;
10071 if (osd_hw.field_out_en[output_index]) {
10072 height = height >> 1;
10073 osd_hw.free_dst_data[index].y_start >>= 1;
10074 }
10075 osd_hw.free_dst_data[index].x_end =
10076 osd_hw.free_dst_data[index].x_start +
10077 width - 1;
10078 osd_hw.free_dst_data[index].y_end =
10079 osd_hw.free_dst_data[index].y_start +
10080 height - 1;
10081
10082 src_height = osd_hw.free_src_data[index].x_end -
10083 osd_hw.free_src_data[index].x_start + 1;
10084 osd_set_dummy_data(index, 0xff);
10085 osd_log_dbg2(MODULE_BLEND, "osd%d:free_src_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +080010086 index,
10087 osd_hw.free_src_data[index].x_start,
10088 osd_hw.free_src_data[index].y_start,
10089 osd_hw.free_src_data[index].x_end,
10090 osd_hw.free_src_data[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080010091 osd_log_dbg2(MODULE_BLEND, "osd%d:free_dst_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +080010092 index,
10093 osd_hw.free_dst_data[index].x_start,
10094 osd_hw.free_dst_data[index].y_start,
10095 osd_hw.free_dst_data[index].x_end,
10096 osd_hw.free_dst_data[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080010097}
10098
10099/* every output is next path input */
10100static void set_blend_path_new(struct hw_osd_blending_s *blending)
10101{
10102 struct layer_blend_s *layer_blend;
Googler9398cc32022-12-02 17:21:52 +080010103 struct osd_blend_reg_s *osd_blend_reg;
10104 struct vpp0_blend_reg_s *vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +080010105 struct dispdata_s output1_data;
10106 u32 index = 0;
10107 u8 input1 = 0, input2 = 0;
10108 u32 output_index;
Googler9398cc32022-12-02 17:21:52 +080010109 s32 position_x, position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010110
10111 if (!blending)
10112 return;
10113 output_index = get_output_device_id(index);
10114
Googler9398cc32022-12-02 17:21:52 +080010115 layer_blend = &blending->layer_blend;
10116 osd_blend_reg = &blending->osd_blend_reg;
10117 vpp0_blend_reg = &blending->vpp0_blend_reg;
Googler4f18c0c2022-09-20 17:23:36 +080010118 layer_blend->blend_core1_bypass = 0;
Googler9398cc32022-12-02 17:21:52 +080010119 memset(&layer_blend->input1_data, 0, sizeof(struct dispdata_s));
10120 memset(&layer_blend->input2_data, 0, sizeof(struct dispdata_s));
10121
Googler9726be62022-12-14 05:53:31 +000010122 if (osd_hw.osd_preblend_en && output_index == VIU1) {
10123 position_x = osd_hw.adjust_position_x;
Googler9398cc32022-12-02 17:21:52 +080010124 position_y = osd_hw.adjust_position_y - osd_hw.preblend_y_offset;
Googler9726be62022-12-14 05:53:31 +000010125 } else {
10126 position_x = osd_hw.disp_info[output_index].position_x;
10127 position_y = osd_hw.disp_info[output_index].position_y;
10128 }
Googler4f18c0c2022-09-20 17:23:36 +080010129 switch (blending->osd_blend_mode) {
10130 case OSD_BLEND_NONE:
Googler9398cc32022-12-02 17:21:52 +080010131 vpp0_blend_reg->postbld_osd1_premult = 0;
10132 vpp0_blend_reg->postbld_src4_sel = POSTBLD_CLOSE;
10133 vpp0_blend_reg->postbld_src3_sel = POSTBLD_CLOSE;
10134 vpp0_blend_reg->postbld_osd2_premult = 0;
Googler4f18c0c2022-09-20 17:23:36 +080010135 break;
10136 case OSD_BLEND_A:
10137 /* sc-->blend0-->blend2-->vpp_osd1 */
10138 layer_blend->input1 = BLEND_DIN1;
Googler9398cc32022-12-02 17:21:52 +080010139 if (osd_hw.blend_bypass[OSD1])
Googler4f18c0c2022-09-20 17:23:36 +080010140 layer_blend->input1 |= BYPASS_DIN;
10141 layer_blend->input2 = BLEND_NO_DIN;
10142 index = blend_din_to_osd(BLEND_DIN1, blending);
10143 if (index >= OSD_MAX)
10144 return;
10145 osd_set_freescale_new(index, blending);
10146 osd_setting_blend0_new(blending);
Googler9398cc32022-12-02 17:21:52 +080010147 if (!osd_blend_reg->din0_byp_blend) {
Googler4f18c0c2022-09-20 17:23:36 +080010148 layer_blend->input1 = BLEND0_DIN;
10149 layer_blend->input2 = BLEND_NO_DIN;
10150 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +080010151 &layer_blend->output_data,
10152 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010153 /* same with blend0's background */
10154 osd_setting_blend2(blending);
10155 }
10156 layer_blend->input1 = BLEND2_DIN;
10157 layer_blend->input2 = BLEND_NO_DIN;
Googler9398cc32022-12-02 17:21:52 +080010158 memcpy(&layer_blend->input1_data,
10159 &layer_blend->output_data,
10160 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010161 layer_blend->input1_data.x +=
Googler9726be62022-12-14 05:53:31 +000010162 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010163 layer_blend->input1_data.y +=
Googler9726be62022-12-14 05:53:31 +000010164 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010165 vpp_setting_blend(blending);
10166 break;
10167 case OSD_BLEND_AC:
10168 /* sc-->blend0 -->blend1-->blend2-->vpp_osd1 */
10169 /* sc-->blend0 & blend1-->blend2-->vpp_osd1 */
10170 if (!blending->b_exchange_din) {
10171 input1 = BLEND_DIN1;
10172 input2 = BLEND_DIN4;
10173 } else {
10174 input1 = BLEND_DIN4;
10175 input2 = BLEND_DIN1;
10176 }
10177 layer_blend->input1 = input1;
10178 layer_blend->input2 = BLEND_NO_DIN;
10179 index = blend_din_to_osd(input1, blending);
10180 if (index >= OSD_MAX)
10181 return;
10182 osd_set_freescale_new(index, blending);
10183 osd_setting_blend0_new(blending);
10184 /* save blend0 output */
Googler9398cc32022-12-02 17:21:52 +080010185 memcpy(&output1_data, &layer_blend->output_data,
10186 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010187
10188 index = blend_din_to_osd(input2, blending);
10189 if (index >= OSD_MAX)
10190 return;
10191 osd_set_freescale_new(index, blending);
10192 layer_blend->input1 = BLEND_NO_DIN;
10193 layer_blend->input2 = input2;
10194 osd_setting_blend1_new(blending);
10195
10196 layer_blend->input1 = BLEND0_DIN;
10197 layer_blend->input2 = BLEND1_DIN;
10198
10199 /* blend0 output-> blend2 input1 */
10200 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +080010201 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010202 /* blend1 output-> blend2 input2 */
10203 memcpy(&layer_blend->input2_data, &layer_blend->output_data,
Googler9398cc32022-12-02 17:21:52 +080010204 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010205 osd_setting_blend2(blending);
10206
10207 layer_blend->input1 = BLEND2_DIN;
10208 layer_blend->input2 = BLEND_NO_DIN;
Googler9398cc32022-12-02 17:21:52 +080010209 memcpy(&layer_blend->input1_data,
10210 &layer_blend->output_data,
10211 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010212 layer_blend->input1_data.x +=
Googler9726be62022-12-14 05:53:31 +000010213 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010214 layer_blend->input1_data.y +=
Googler9726be62022-12-14 05:53:31 +000010215 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010216 vpp_setting_blend(blending);
10217 break;
10218 case OSD_BLEND_A_C:
10219 /* sc-->blend0 -->blend2->vpp_osd1 */
10220 /* sc-->blend1 -->vpp_osd2 */
10221 layer_blend->input1 = BLEND_DIN1;
Googler9398cc32022-12-02 17:21:52 +080010222 if (osd_hw.blend_bypass[OSD1])
Googler4f18c0c2022-09-20 17:23:36 +080010223 layer_blend->input1 |= BYPASS_DIN;
10224 layer_blend->input2 = BLEND_NO_DIN;
10225 index = blend_din_to_osd(BLEND_DIN1, blending);
10226 if (index >= OSD_MAX)
10227 return;
10228 osd_set_freescale_new(index, blending);
10229 osd_setting_blend0_new(blending);
Googler9398cc32022-12-02 17:21:52 +080010230 if (!osd_blend_reg->din0_byp_blend) {
Googler4f18c0c2022-09-20 17:23:36 +080010231 layer_blend->input1 = BLEND0_DIN;
10232 layer_blend->input2 = BLEND_NO_DIN;
10233 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +080010234 &layer_blend->output_data,
10235 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010236 /* background is same with blend0's background */
10237 osd_setting_blend2(blending);
10238 }
10239 /* save blend0/blend2 output */
Googler9398cc32022-12-02 17:21:52 +080010240 memcpy(&output1_data, &layer_blend->output_data,
10241 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010242 /* adjust input 1 offset*/
10243 output1_data.x +=
Googler9726be62022-12-14 05:53:31 +000010244 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010245 output1_data.y +=
Googler9726be62022-12-14 05:53:31 +000010246 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010247
10248 index = blend_din_to_osd(BLEND_DIN4, blending);
10249 if (index >= OSD_MAX)
10250 return;
10251 osd_set_freescale_new(index, blending);
10252 layer_blend->input1 = BLEND_NO_DIN;
10253 layer_blend->input2 = BLEND_DIN4 | BYPASS_DIN;
10254 layer_blend->blend_core1_bypass = 1;
10255 osd_setting_blend1_new(blending);
10256 /* adjust input 2 offset*/
10257 layer_blend->output_data.x +=
Googler9726be62022-12-14 05:53:31 +000010258 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010259 layer_blend->output_data.y +=
Googler9726be62022-12-14 05:53:31 +000010260 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010261
10262 if (!blending->b_exchange_blend_in) {
10263 layer_blend->input1 = BLEND2_DIN;
10264 layer_blend->input2 = BLEND1_DIN;
10265 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +080010266 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010267 memcpy(&layer_blend->input2_data,
Googler9398cc32022-12-02 17:21:52 +080010268 &layer_blend->output_data,
Googler4f18c0c2022-09-20 17:23:36 +080010269 sizeof(struct dispdata_s));
10270 } else {
10271 layer_blend->input1 = BLEND1_DIN;
10272 layer_blend->input2 = BLEND2_DIN;
10273 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +080010274 &layer_blend->output_data,
10275 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010276 memcpy(&layer_blend->input2_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +080010277 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010278 }
10279 vpp_setting_blend(blending);
10280 break;
10281 case OSD_BLEND_ABC:
10282 /* sc->blend0 -->blend2-->vpp_osd1 */
10283 /* sc-->blend1 -->blend2 */
10284 input1 = BLEND_DIN1;
10285 input2 = BLEND_DIN4;
10286 layer_blend->input1 = input1;
10287 layer_blend->input2 = BLEND_NO_DIN;
10288 index = blend_din_to_osd(input1, blending);
10289 if (index >= OSD_MAX)
10290 return;
10291 osd_set_freescale_new(index, blending);
10292 osd_setting_blend0_new(blending);
10293 /* save blend0 output */
Googler9398cc32022-12-02 17:21:52 +080010294 memcpy(&output1_data, &layer_blend->output_data,
10295 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010296
10297 layer_blend->input1 = BLEND_DIN3;
10298 layer_blend->input2 = input2;
10299 index = blend_din_to_osd(layer_blend->input1, blending);
10300 osd_set_freescale_new(index, blending);
10301 index = blend_din_to_osd(layer_blend->input2, blending);
10302 osd_set_freescale_new(index, blending);
10303 osd_setting_blend1_new(blending);
10304
10305 layer_blend->input1 = BLEND0_DIN;
10306 layer_blend->input2 = BLEND1_DIN;
10307 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +080010308 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010309 memcpy(&layer_blend->input2_data, &layer_blend->output_data,
Googler9398cc32022-12-02 17:21:52 +080010310 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010311 osd_setting_blend2(blending);
10312
10313 layer_blend->input1 = BLEND2_DIN;
10314 layer_blend->input2 = BLEND_NO_DIN;
Googler9398cc32022-12-02 17:21:52 +080010315 memcpy(&layer_blend->input1_data,
10316 &layer_blend->output_data,
10317 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010318 layer_blend->input1_data.x +=
Googler9726be62022-12-14 05:53:31 +000010319 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010320 layer_blend->input1_data.y +=
Googler9726be62022-12-14 05:53:31 +000010321 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010322 vpp_setting_blend(blending);
10323 break;
10324 case OSD_BLEND_AB_C:
10325 /* sc-->blend0 -->blend2->vpp_osd1 */
10326 /* sc-->blend1-->blend2-->vpp_osd1 */
10327 /* sc -->vpp_osd2 */
10328 layer_blend->input1 = BLEND_DIN1;
10329 layer_blend->input2 = BLEND_NO_DIN;
10330 blending->blend_din = BLEND_DIN1;
10331 index = blend_din_to_osd(BLEND_DIN1, blending);
10332 if (index >= OSD_MAX)
10333 return;
10334 osd_set_freescale_new(index, blending);
10335 osd_setting_blend0_new(blending);
10336 /* save blend0 output */
Googler9398cc32022-12-02 17:21:52 +080010337 memcpy(&output1_data, &layer_blend->output_data,
10338 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010339
10340 /* din3 input to blend1 */
10341 layer_blend->input1 = BLEND_DIN3;
10342 layer_blend->input2 = BLEND_NO_DIN | BYPASS_DIN;
10343 layer_blend->blend_core1_bypass = 1;
10344 blending->blend_din = BLEND_DIN3;
10345 index = blend_din_to_osd(BLEND_DIN3, blending);
10346 osd_set_freescale_new(index, blending);
10347 osd_setting_blend1_new(blending);
10348
10349 /* din1=>blend0 & din3-> blend1 ==> blend2 */
10350 layer_blend->input1 = BLEND0_DIN;
10351 layer_blend->input2 = BLEND1_DIN;
10352 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +080010353 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010354 memcpy(&layer_blend->input2_data, &layer_blend->output_data,
Googler9398cc32022-12-02 17:21:52 +080010355 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010356 osd_setting_blend2(blending);
Googler9398cc32022-12-02 17:21:52 +080010357 memcpy(&output1_data, &layer_blend->output_data,
10358 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010359 output1_data.x +=
Googler9726be62022-12-14 05:53:31 +000010360 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010361 output1_data.y +=
Googler9726be62022-12-14 05:53:31 +000010362 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010363 osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +080010364 output1_data.x,
Googler4f18c0c2022-09-20 17:23:36 +080010365 output1_data.w,
10366 output1_data.y,
10367 output1_data.h);
10368
Googler4f18c0c2022-09-20 17:23:36 +080010369 /* din4 ==> vpp */
10370 index = blend_din_to_osd(BLEND_DIN4, blending);
10371 blending->blend_din = BLEND_DIN4;
10372 osd_set_freescale_new(index, blending);
10373 layer_blend->input2_data.x =
10374 osd_hw.free_dst_data[index].x_start +
Googler9726be62022-12-14 05:53:31 +000010375 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010376 layer_blend->input2_data.w =
10377 osd_hw.free_dst_data[index].x_end -
10378 osd_hw.free_dst_data[index].x_start + 1;
10379 layer_blend->input2_data.y =
10380 osd_hw.free_dst_data[index].y_start +
Googler9726be62022-12-14 05:53:31 +000010381 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010382 layer_blend->input2_data.h =
10383 osd_hw.free_dst_data[index].y_end -
10384 osd_hw.free_dst_data[index].y_start + 1;
10385
10386 /* 2vpp input */
10387 if (!blending->b_exchange_blend_in) {
10388 layer_blend->input1 = BLEND2_DIN;
10389 layer_blend->input2 = BLEND1_DIN;
10390 memcpy(&layer_blend->input1_data, &output1_data,
Googler9398cc32022-12-02 17:21:52 +080010391 sizeof(struct dispdata_s));
Googler4f18c0c2022-09-20 17:23:36 +080010392 } else {
10393 layer_blend->input1 = BLEND1_DIN;
10394 layer_blend->input2 = BLEND2_DIN;
10395 memcpy(&layer_blend->input1_data,
Googler9398cc32022-12-02 17:21:52 +080010396 &layer_blend->input2_data,
Googler4f18c0c2022-09-20 17:23:36 +080010397 sizeof(struct dispdata_s));
10398 memcpy(&layer_blend->input2_data,
Googler9398cc32022-12-02 17:21:52 +080010399 &output1_data,
10400 sizeof(struct dispdata_s));
10401 }
10402 vpp_setting_blend(blending);
10403 break;
10404 case OSD_BLEND_ABCD:
10405 /* sc->blend0 -->blend2-->vpp_osd1 */
10406 /* sc-->blend1 -->blend2 */
10407 layer_blend->input1 = BLEND_DIN1;
10408 layer_blend->input2 = BLEND_DIN2;
10409 index = blend_din_to_osd(layer_blend->input1, blending);
10410 if (index >= OSD_MAX)
10411 return;
10412 osd_set_freescale_new(index, blending);
10413 index = blend_din_to_osd(layer_blend->input2, blending);
10414 if (index >= OSD_MAX)
10415 return;
10416 osd_set_freescale_new(index, blending);
10417 osd_setting_blend0_new(blending);
10418 /* save blend0 output */
10419 memcpy(&output1_data,
10420 &layer_blend->output_data,
10421 sizeof(struct dispdata_s));
10422
10423 layer_blend->input1 = BLEND_DIN3;
10424 layer_blend->input2 = BLEND_DIN4;
10425 index = blend_din_to_osd(layer_blend->input1, blending);
10426 osd_set_freescale_new(index, blending);
10427 index = blend_din_to_osd(layer_blend->input2, blending);
10428 osd_set_freescale_new(index, blending);
10429 osd_setting_blend1_new(blending);
10430 /* save blend1 output */
10431 memcpy(&layer_blend->input1_data,
10432 &output1_data,
10433 sizeof(struct dispdata_s));
10434 memcpy(&layer_blend->input2_data,
10435 &layer_blend->output_data,
10436 sizeof(struct dispdata_s));
10437
10438 layer_blend->input1 = BLEND0_DIN;
10439 layer_blend->input2 = BLEND1_DIN;
10440 osd_setting_blend2(blending);
10441
10442 layer_blend->input1 = BLEND2_DIN;
10443 layer_blend->input2 = BLEND_NO_DIN;
10444 memcpy(&layer_blend->input1_data,
10445 &layer_blend->output_data,
10446 sizeof(struct dispdata_s));
10447 layer_blend->input1_data.x +=
10448 position_x;
10449 layer_blend->input1_data.y +=
10450 position_y;
10451 vpp_setting_blend(blending);
10452 break;
10453 case OSD_BLEND_AB_CD:
10454 /* sc->blend0 -->blend2-->vpp_osd1 */
10455 /* sc-->blend1 -->blend2 */
10456 layer_blend->input1 = BLEND_DIN1;
10457 layer_blend->input2 = BLEND_DIN2;
10458 index = blend_din_to_osd(layer_blend->input1, blending);
10459 if (index >= OSD_MAX)
10460 return;
10461 osd_set_freescale_new(index, blending);
10462 index = blend_din_to_osd(layer_blend->input2, blending);
10463 if (index >= OSD_MAX)
10464 return;
10465 osd_set_freescale_new(index, blending);
10466 osd_setting_blend0_new(blending);
10467 /* save blend0 output */
10468 memcpy(&layer_blend->input1_data,
10469 &layer_blend->output_data,
10470 sizeof(struct dispdata_s));
10471 layer_blend->input1 = BLEND0_DIN;
10472 layer_blend->input2 = BLEND_NO_DIN;
10473 osd_setting_blend2(blending);
10474 /* save blend2 output */
10475 memcpy(&output1_data,
10476 &layer_blend->output_data,
10477 sizeof(struct dispdata_s));
10478
10479 /* always route(bypass) to dout1 */
10480 layer_blend->input1 = BLEND_DIN3;
10481 layer_blend->input2 = BLEND_DIN4;
10482
10483 index = blend_din_to_osd(layer_blend->input1, blending);
10484 osd_set_freescale_new(index, blending);
10485 index = blend_din_to_osd(layer_blend->input2, blending);
10486 osd_set_freescale_new(index, blending);
10487
10488 layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN;
10489 osd_setting_blend1_new(blending);
10490 /* save blend1 output */
10491 memcpy(&layer_blend->input1_data,
10492 &output1_data,
10493 sizeof(struct dispdata_s));
10494
10495 memcpy(&layer_blend->input2_data,
10496 &layer_blend->output_data,
10497 sizeof(struct dispdata_s));
10498
10499 if (!blending->b_exchange_blend_in) {
10500 layer_blend->input1 = BLEND2_DIN;
10501 layer_blend->input2 = BLEND1_DIN;
10502 memcpy(&layer_blend->input1_data, &output1_data,
10503 sizeof(struct dispdata_s));
10504 layer_blend->input1_data.x +=
10505 position_x;
10506 layer_blend->input1_data.y +=
10507 position_y;
10508 memcpy(&layer_blend->input2_data,
10509 &layer_blend->output_data,
10510 sizeof(struct dispdata_s));
10511 layer_blend->input2_data.x +=
10512 position_x;
10513 layer_blend->input2_data.y +=
10514 position_y;
10515 } else {
10516 layer_blend->input1 = BLEND1_DIN;
10517 layer_blend->input2 = BLEND2_DIN;
10518 memcpy(&layer_blend->input1_data,
10519 &layer_blend->output_data,
10520 sizeof(struct dispdata_s));
10521 layer_blend->input1_data.x +=
10522 position_x;
10523 layer_blend->input1_data.y +=
10524 position_y;
10525 memcpy(&layer_blend->input2_data,
Googler4f18c0c2022-09-20 17:23:36 +080010526 &output1_data,
10527 sizeof(struct dispdata_s));
Googler9398cc32022-12-02 17:21:52 +080010528 layer_blend->input2_data.x +=
10529 position_x;
10530 layer_blend->input2_data.y +=
10531 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010532 }
10533 vpp_setting_blend(blending);
10534 break;
10535 }
10536}
10537
Googler9398cc32022-12-02 17:21:52 +080010538static void osd_set_vpp_path(u32 vpp_osd_index, u32 vpp_index)
10539{
10540 struct osd_rdma_fun_s *rdma_func = &osd_hw.osd_rdma_func[vpp_index];
10541 osd_rdma_wr_bits_op rdma_wr_bits = rdma_func->osd_rdma_wr_bits;
10542
10543 if (osd_dev_hw.has_multi_vpp) {
10544 /* osd_index is vpp mux input */
10545 /* default setting osd2 route to vpp0 vsync */
10546 if (vpp_osd_index == VPP_OSD3)
10547 rdma_wr_bits(PATH_START_SEL, vpp_index, 24, 2);
10548 /* default setting osd3 route to vpp0 vsync */
10549 if (vpp_osd_index == VPP_OSD4)
10550 rdma_wr_bits(PATH_START_SEL, vpp_index, 28, 2);
10551 }
10552}
10553
10554static void set_osd_hdr_size_in(u32 osd_index, u32 osd_hsize, u32 osd_vsize)
10555{
10556 u32 output_index = get_output_device_id(osd_index);
10557
10558 switch (osd_index) {
10559 case VPP_OSD1:
10560 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
10561 (OSD1_HDR_IN_SIZE,
10562 osd_vsize << 16 | osd_hsize);
10563 break;
10564 case VPP_OSD2:
10565 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
10566 (OSD2_HDR_IN_SIZE,
10567 osd_vsize << 16 | osd_hsize);
10568 break;
10569 case VPP_OSD3:
10570 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
10571 (OSD3_HDR_IN_SIZE,
10572 osd_vsize << 16 | osd_hsize);
10573 break;
10574 case VPP_OSD4:
10575 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
10576 (OSD4_HDR_IN_SIZE,
10577 osd_vsize << 16 | osd_hsize);
10578 break;
10579 default:
10580 break;
10581 }
10582}
10583
10584static void set_vpp0_blend_reg(struct vpp0_blend_reg_s *vpp0_blend_reg)
10585{
10586 VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_H_SCOPE,
10587 vpp0_blend_reg->osd1_h_start << 16 |
10588 vpp0_blend_reg->osd1_h_end);
10589 VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_V_SCOPE,
10590 vpp0_blend_reg->osd1_v_start << 16 |
10591 vpp0_blend_reg->osd1_v_end);
10592 VSYNCOSD_WR_MPEG_REG(VPP_OSD2_BLD_H_SCOPE,
10593 vpp0_blend_reg->osd2_h_start << 16 |
10594 vpp0_blend_reg->osd2_h_end);
10595 VSYNCOSD_WR_MPEG_REG(VPP_OSD2_BLD_V_SCOPE,
10596 vpp0_blend_reg->osd2_v_start << 16 |
10597 vpp0_blend_reg->osd2_v_end);
10598 /* vpp osd1 blend ctrl */
10599 VSYNCOSD_WR_MPEG_REG(OSD1_BLEND_SRC_CTRL,
10600 (vpp0_blend_reg->prebld_src3_sel & 0xf) << 0 |
10601 (0 & 0x1) << 4 |
10602 (vpp0_blend_reg->postbld_src3_sel & 0xf) << 8 |
10603 (0 << 16) |
10604 ((!osd_hw.osd_preblend_en) & 0x1) << 20);
10605 /* vpp osd2 blend ctrl */
10606 if (!enable_vd_zorder)
10607 VSYNCOSD_WR_MPEG_REG(OSD2_BLEND_SRC_CTRL,
10608 (vpp0_blend_reg->prebld_src4_sel & 0xf) << 0 |
10609 (0 & 0x1) << 4 |
10610 (vpp0_blend_reg->postbld_src4_sel & 0xf) << 8 |
10611 (0 << 16) |
10612 ((!osd_hw.osd_preblend_en) & 0x1) << 20);
10613
10614 if (osd_dev_hw.has_multi_vpp) {
10615 u32 osd_hsize, osd_vsize;
10616
10617 /* vsync select */
10618 osd_set_vpp_path(vpp0_blend_reg->osd1_index, VPU_VPP0);
10619 osd_set_vpp_path(vpp0_blend_reg->osd2_index, VPU_VPP0);
10620 /* hdr size input */
10621 osd_hsize = vpp0_blend_reg->osd1_h_end -
10622 vpp0_blend_reg->osd1_h_start + 1;
10623 osd_vsize = vpp0_blend_reg->osd1_v_end -
10624 vpp0_blend_reg->osd1_v_start + 1;
10625 set_osd_hdr_size_in(vpp0_blend_reg->osd1_index,
10626 osd_hsize,
10627 osd_vsize);
10628 osd_hsize = vpp0_blend_reg->osd2_h_end -
10629 vpp0_blend_reg->osd2_h_start + 1;
10630 osd_vsize = vpp0_blend_reg->osd2_v_end -
10631 vpp0_blend_reg->osd2_v_start + 1;
10632 set_osd_hdr_size_in(vpp0_blend_reg->osd2_index,
10633 osd_hsize,
10634 osd_vsize);
10635 /* vpp input mux */
10636 VSYNCOSD_WR_MPEG_REG_BITS(OSD_PATH_MISC_CTRL,
10637 vpp0_blend_reg->osd1_index |
10638 vpp0_blend_reg->osd2_index << 4,
10639 16, 8);
10640 }
10641}
10642
10643static void set_osd_blend_reg(struct osd_blend_reg_s *osd_blend_reg)
Googler4f18c0c2022-09-20 17:23:36 +080010644{
10645 int i;
10646 u32 reg_offset = 2;
Googler4f18c0c2022-09-20 17:23:36 +080010647 u32 osd_count = OSD_BLEND_LAYERS;
10648 u32 dv_core2_hsize;
10649 u32 dv_core2_vsize;
Googler9398cc32022-12-02 17:21:52 +080010650 u32 osd1_alpha_div = 0, osd2_alpha_div = 0;
Googler4f18c0c2022-09-20 17:23:36 +080010651
Googler9398cc32022-12-02 17:21:52 +080010652 if (!osd_blend_reg)
Googler4f18c0c2022-09-20 17:23:36 +080010653 return;
Googler9398cc32022-12-02 17:21:52 +080010654
10655 osd1_alpha_div = osd_blend_reg->osd_bld_out0_premult;
10656 osd2_alpha_div = osd_blend_reg->osd_bld_out1_premult;
Googler4f18c0c2022-09-20 17:23:36 +080010657 /* osd0 scale position before osd blend */
10658 if (osd_hw.osd_meson_dev.osd0_sc_independ)
10659 VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_CTRL, 0x01);
Googler9398cc32022-12-02 17:21:52 +080010660 if (osd_hw.blend_bypass[OSD1])
10661 osd_blend_reg->din0_byp_blend = 1;
Googler4f18c0c2022-09-20 17:23:36 +080010662 /* osd blend ctrl */
Googler9398cc32022-12-02 17:21:52 +080010663 VSYNCOSD_WR_MPEG_REG
10664 (VIU_OSD_BLEND_CTRL,
10665 4 << 29 |
10666 osd_blend_reg->blend2_premult_en << 27 |
10667 osd_blend_reg->din0_byp_blend << 26 |
10668 osd_blend_reg->din2_osd_sel << 25 |
10669 osd_blend_reg->din3_osd_sel << 24 |
10670 osd_blend_reg->blend_din_en << 20 |
10671 osd_blend_reg->din_premult_en << 16 |
10672 osd_blend_reg->din_reoder_sel);
10673
Googler4f18c0c2022-09-20 17:23:36 +080010674 /* VIU_OSD_BLEND_CTRL1 */
10675 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_CTRL1,
Googler9398cc32022-12-02 17:21:52 +080010676 (osd1_alpha_div & 0x1) |
10677 (3 << 4) |
10678 ((osd2_alpha_div & 0x1) << 12) |
10679 (3 << 16));
Googler4f18c0c2022-09-20 17:23:36 +080010680
10681 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE,
Googler9398cc32022-12-02 17:21:52 +080010682 osd_blend_reg->osd_blend_blend0_size);
Googler9726be62022-12-14 05:53:31 +000010683 /* hdr input size should set to osd blend0 output size */
10684 VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE,
Googler9398cc32022-12-02 17:21:52 +080010685 osd_blend_reg->osd_blend_blend0_size);
10686 VSYNCOSD_WR_MPEG_REG(OSD1_HDR_IN_SIZE,
10687 osd_blend_reg->osd_blend_blend0_size);
Googler9726be62022-12-14 05:53:31 +000010688
Googler4f18c0c2022-09-20 17:23:36 +080010689 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE,
Googler9398cc32022-12-02 17:21:52 +080010690 osd_blend_reg->osd_blend_blend1_size);
Googler4f18c0c2022-09-20 17:23:36 +080010691 for (i = 0; i < osd_count; i++) {
10692 if (osd_hw.enable[i]) {
Googler9398cc32022-12-02 17:21:52 +080010693 VSYNCOSD_WR_MPEG_REG
10694 (VIU_OSD_BLEND_DIN0_SCOPE_H +
10695 reg_offset * i,
10696 osd_blend_reg->osd_blend_din_scope_h[i]);
Googler9726be62022-12-14 05:53:31 +000010697 }
Googler9398cc32022-12-02 17:21:52 +080010698 if ((osd_blend_reg->osd_blend_din_scope_v[i] & 0xffff0000) == 0)
10699 osd_blend_reg->osd_blend_din_scope_v[i] =
Googler9726be62022-12-14 05:53:31 +000010700 0xffffffff;
Googler9398cc32022-12-02 17:21:52 +080010701 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_DIN0_SCOPE_V +
10702 reg_offset * i,
10703 osd_blend_reg->osd_blend_din_scope_v[i]);
Googler4f18c0c2022-09-20 17:23:36 +080010704 }
10705
Googler9398cc32022-12-02 17:21:52 +080010706 dv_core2_vsize = (osd_blend_reg->osd_blend_blend0_size >> 16) & 0xfff;
10707 dv_core2_hsize = osd_blend_reg->osd_blend_blend0_size & 0xfff;
Googler4f18c0c2022-09-20 17:23:36 +080010708
10709 if (osd_hw.osd_meson_dev.has_dolby_vision) {
Googler9398cc32022-12-02 17:21:52 +080010710 VSYNCOSD_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL1,
10711 ((dv_core2_hsize + 0x40) << 16)
10712 | (dv_core2_vsize + 0x80 + 0));
10713 VSYNCOSD_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL2,
10714 (dv_core2_hsize << 16) |
10715 (dv_core2_vsize + 0));
Googler4f18c0c2022-09-20 17:23:36 +080010716#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
Googler9726be62022-12-14 05:53:31 +000010717 update_graphic_width_height(dv_core2_hsize, dv_core2_vsize);
10718 if (!update_to_dv) {
10719 update_graphic_status();
10720 update_to_dv = true;
10721 }
Googler4f18c0c2022-09-20 17:23:36 +080010722#endif
10723 }
Googler9398cc32022-12-02 17:21:52 +080010724}
Googler9726be62022-12-14 05:53:31 +000010725
Googler9398cc32022-12-02 17:21:52 +080010726static void set_blend_reg(struct hw_osd_blending_s *blending)
10727{
10728 set_osd_blend_reg(&blending->osd_blend_reg);
10729 set_vpp0_blend_reg(&blending->vpp0_blend_reg);
Googler4f18c0c2022-09-20 17:23:36 +080010730}
10731
10732static void uniformization_fb(u32 index,
Googler9398cc32022-12-02 17:21:52 +080010733 struct hw_osd_blending_s *blending)
Googler4f18c0c2022-09-20 17:23:36 +080010734{
Googler9398cc32022-12-02 17:21:52 +080010735 if (index == OSD1 && osd_hw.src_crop[index] &&
10736 !osd_hw.osd_preblend_en) {
Googler9726be62022-12-14 05:53:31 +000010737 blending->screen_ratio_w_den =
10738 osd_hw.src_data[index].w;
10739 blending->screen_ratio_h_den =
10740 osd_hw.src_data[index].h;
10741 }
Googler38bda472022-08-19 10:07:08 -070010742 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +080010743 "uniformization:osd%d:blending screen_ratio:%d,%d,%d,%d\n",
10744 index,
10745 blending->screen_ratio_w_den,
10746 blending->screen_ratio_h_den,
10747 blending->screen_ratio_w_num,
10748 blending->screen_ratio_h_num);
10749
10750 blending->dst_data.x = osd_hw.dst_data[index].x *
10751 blending->screen_ratio_w_den /
10752 blending->screen_ratio_w_num;
10753 blending->dst_data.y = osd_hw.dst_data[index].y *
10754 blending->screen_ratio_h_den /
10755 blending->screen_ratio_h_num;
10756 blending->dst_data.w = osd_hw.dst_data[index].w *
10757 blending->screen_ratio_w_den /
10758 blending->screen_ratio_w_num;
10759 blending->dst_data.h = osd_hw.dst_data[index].h *
10760 blending->screen_ratio_h_den /
10761 blending->screen_ratio_h_num;
10762
10763 osd_log_dbg2(MODULE_BLEND,
10764 "uniformization:osd%d:dst_data:%d,%d,%d,%d\n",
10765 index,
10766 blending->dst_data.x,
10767 blending->dst_data.y,
10768 blending->dst_data.w,
10769 blending->dst_data.h);
Googler4f18c0c2022-09-20 17:23:36 +080010770}
10771
10772static void adjust_dst_position(u32 output_index)
10773{
10774 int i = 0;
10775 int osd_count = 0;
10776 int start_index = 0;
Googler9726be62022-12-14 05:53:31 +000010777 u32 position_x, position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010778
10779 if (output_index == VIU1) {
10780 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
10781 start_index = 0;
10782 } else if (output_index == VIU2) {
10783 start_index = osd_hw.osd_meson_dev.viu2_index;
10784 osd_count = start_index + 1;
10785 } else {
Googler9398cc32022-12-02 17:21:52 +080010786 osd_log_err("invalid output_index=%d\n", output_index);
Googler4f18c0c2022-09-20 17:23:36 +080010787 return;
10788 }
10789
Googler9398cc32022-12-02 17:21:52 +080010790 if (osd_hw.osd_preblend_en && output_index == VIU1) {
Googler9726be62022-12-14 05:53:31 +000010791 position_x = osd_hw.adjust_position_x;
10792 position_y = osd_hw.adjust_position_y;
10793 } else {
10794 position_x = osd_hw.disp_info[output_index].position_x;
10795 position_y = osd_hw.disp_info[output_index].position_y;
10796 }
10797 osd_log_dbg2(MODULE_BLEND,
10798 "adjust dst_data:osd%d, position x=%d,y=%d\n",
10799 i,
10800 position_x,
10801 position_y);
Googler4f18c0c2022-09-20 17:23:36 +080010802 for (i = 0; i < osd_count; i++) {
Googler9398cc32022-12-02 17:21:52 +080010803 if (osd_hw.enable[i] && validate_osd(i, output_index)) {
Googler4f18c0c2022-09-20 17:23:36 +080010804 osd_hw.dst_data[i].x -=
Googler9726be62022-12-14 05:53:31 +000010805 position_x;
Googler4f18c0c2022-09-20 17:23:36 +080010806 osd_hw.dst_data[i].y -=
Googler9726be62022-12-14 05:53:31 +000010807 position_y;
Googler4f18c0c2022-09-20 17:23:36 +080010808 if (osd_hw.dst_data[i].x < 0)
10809 osd_hw.dst_data[i].x = 0;
10810 if (osd_hw.dst_data[i].y < 0)
10811 osd_hw.dst_data[i].y = 0;
10812 osd_log_dbg2(MODULE_BLEND,
Googler9398cc32022-12-02 17:21:52 +080010813 "adjust dst_data:osd%d:%d,%d,%d,%d\n",
Googler38bda472022-08-19 10:07:08 -070010814 i,
10815 osd_hw.dst_data[i].x,
10816 osd_hw.dst_data[i].y,
10817 osd_hw.dst_data[i].w,
10818 osd_hw.dst_data[i].h);
Googler4f18c0c2022-09-20 17:23:36 +080010819 }
10820 }
Googler9398cc32022-12-02 17:21:52 +080010821 if (osd_hw.field_out_en[output_index])
10822 osd_hw.disp_info[output_index].position_y /= 2;
Googler4f18c0c2022-09-20 17:23:36 +080010823}
10824
Googler9398cc32022-12-02 17:21:52 +080010825#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
10826void osd_secure_cb(u32 arg)
10827{
10828 osd_log_dbg(MODULE_SECURE, "%s: arg=%x, secure_src=%x, reg:%x\n",
10829 __func__,
10830 arg, osd_hw.secure_src,
10831 osd_reg_read(VIU_DATA_SEC));
10832}
10833#endif
10834
Googler4f18c0c2022-09-20 17:23:36 +080010835static int osd_setting_order(u32 output_index)
10836{
Googler9398cc32022-12-02 17:21:52 +080010837#define RDMA_DETECT_REG VIU_OSD2_TCOLOR_AG0
Googler4f18c0c2022-09-20 17:23:36 +080010838 int i;
Googler4f18c0c2022-09-20 17:23:36 +080010839 struct hw_osd_blending_s *blending;
Googler9398cc32022-12-02 17:21:52 +080010840 u32 osd_count = osd_hw.osd_meson_dev.osd_count;
Googler4f18c0c2022-09-20 17:23:36 +080010841 int line1;
10842 int line2;
Googler9726be62022-12-14 05:53:31 +000010843 int active_begin_line;
10844 u32 val, wait_cnt = 0;
10845#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
10846 u32 secure_src = 0;
10847#endif
10848 u32 total_line;
Googler4f18c0c2022-09-20 17:23:36 +080010849
10850 blending = &osd_blending;
Googler4f18c0c2022-09-20 17:23:36 +080010851
10852 blending->vinfo_width = osd_hw.vinfo_width[output_index];
10853 blending->vinfo_height = osd_hw.vinfo_height[output_index];
Googler9726be62022-12-14 05:53:31 +000010854 blending->screen_ratio_w_num =
10855 osd_hw.disp_info[output_index].position_w;
10856 blending->screen_ratio_w_den =
10857 osd_hw.disp_info[output_index].background_w;
10858 blending->screen_ratio_h_num =
10859 osd_hw.disp_info[output_index].position_h;
10860 blending->screen_ratio_h_den =
10861 osd_hw.disp_info[output_index].background_h;
Googler9726be62022-12-14 05:53:31 +000010862
Googler9398cc32022-12-02 17:21:52 +080010863 if (osd_hw.osd_preblend_en) {
10864 blending->screen_ratio_w_num =
10865 blending->screen_ratio_w_num *
10866 osd_hw.preblend_pps_w_den /
10867 osd_hw.preblend_pps_w_num;
10868
10869 blending->screen_ratio_h_num =
10870 blending->screen_ratio_h_num *
10871 osd_hw.preblend_pps_h_den /
10872 osd_hw.preblend_pps_h_num;
10873 osd_log_dbg2(MODULE_BLEND,
10874 "blending screen_ratio:%d,%d,%d,%d\n",
10875 blending->screen_ratio_w_den,
10876 blending->screen_ratio_h_den,
10877 blending->screen_ratio_w_num,
10878 blending->screen_ratio_h_num);
Googler9726be62022-12-14 05:53:31 +000010879 }
Googler9398cc32022-12-02 17:21:52 +080010880
10881 blending->layer_cnt = get_available_layers(output_index);
10882 set_blend_order(blending, output_index);
Googler4f18c0c2022-09-20 17:23:36 +080010883
10884 osd_log_dbg(MODULE_BLEND, "layer_cnt:%d\n",
Googler9398cc32022-12-02 17:21:52 +080010885 blending->layer_cnt);
Googler4f18c0c2022-09-20 17:23:36 +080010886
Googler9398cc32022-12-02 17:21:52 +080010887 blending->b_exchange_din = 0;
10888 blending->b_exchange_blend_in = 0;
10889 blending->osd1_freescale_disable = 0;
Googler4f18c0c2022-09-20 17:23:36 +080010890 adjust_dst_position(output_index);
10891 if (!osd_hw.osd_meson_dev.osd0_sc_independ)
10892 uniformization_fb(OSD1, blending);
10893
10894 /* set blend mode */
10895 set_blend_mode(blending);
10896 generate_blend_din_table(blending);
10897
10898 set_blend_din(blending);
10899
10900 /* set blend path */
10901 if (osd_hw.osd_meson_dev.osd0_sc_independ)
10902 set_blend_path_new(blending);
10903 else
10904 set_blend_path(blending);
Googler9726be62022-12-14 05:53:31 +000010905 active_begin_line = get_active_begin_line(VIU1);
10906 line1 = get_enter_encp_line(VIU1);
Googler4f18c0c2022-09-20 17:23:36 +080010907 /* if nearly vsync signal, wait vsync here */
Googler9726be62022-12-14 05:53:31 +000010908 if (osd_hw.field_out_en[VIU1] && is_encp(VIU1)) {
10909 total_line = osd_hw.vinfo_height[VIU1] + active_begin_line;
10910 if (line1 >= total_line)
10911 /* bottom*/
10912 line1 -= total_line;
10913 } else {
10914 total_line = osd_hw.vinfo_height[VIU1] + active_begin_line;
Googler38bda472022-08-19 10:07:08 -070010915 }
Googler9726be62022-12-14 05:53:31 +000010916
10917 while (line1 >= total_line *
Googler9398cc32022-12-02 17:21:52 +080010918 (100 - line_threshold) / 100 ||
10919 line1 <= active_begin_line * line_threshold_2 / 100) {
Googler9726be62022-12-14 05:53:31 +000010920 /* 0.5ms */
10921 usleep_range(500, 600);
10922 wait_cnt++;
10923 if (wait_cnt >= WAIT_CNT_MAX)
10924 break;
10925 line1 = get_enter_encp_line(VIU1);
10926 }
10927 if (wait_cnt > 0)
10928 osd_hw.rdma_delayed_cnt1++;
Googler4f18c0c2022-09-20 17:23:36 +080010929 spin_lock_irqsave(&osd_lock, lock_flags);
10930 if (blending->osd1_freescale_disable)
10931 osd_hw.reg[DISP_FREESCALE_ENABLE].update_func(OSD1);
10932 for (i = 0; i < osd_count; i++) {
Googler9398cc32022-12-02 17:21:52 +080010933 if (!validate_osd(i, output_index))
10934 continue;
10935
Googler4f18c0c2022-09-20 17:23:36 +080010936 if (osd_hw.enable[i]) {
10937 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[i];
Googler9726be62022-12-14 05:53:31 +000010938 enum color_index_e idx = COLOR_INDEX_32_BGRX;
10939 bool rgbx = false;
Googler4f18c0c2022-09-20 17:23:36 +080010940
Googler9726be62022-12-14 05:53:31 +000010941 if (osd_hw.color_info[i])
10942 idx = osd_hw.color_info[i]->color_index;
10943 else
10944 osd_log_err("osd%d color_info is NULL\n", i);
10945 /* update = is_freescale_para_changed(i); */
Googler9398cc32022-12-02 17:21:52 +080010946 if (!osd_hw.osd_afbcd[i].enable) {
10947 if (osd_hw.osd_meson_dev.mif_linear)
10948 osd_update_mif_linear_addr(i);
10949 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
10950 else
10951 canvas_config(osd_hw.fb_gem[i].canvas_idx,
10952 osd_hw.fb_gem[i].addr,
10953 CANVAS_ALIGNED
10954 (osd_hw.fb_gem[i].width),
10955 osd_hw.fb_gem[i].height,
10956 CANVAS_ADDR_NOWRAP,
10957 CANVAS_BLKMODE_LINEAR);
10958 #endif
10959 }
Googler9726be62022-12-14 05:53:31 +000010960 osd_set_scan_mode(i);
Googler4f18c0c2022-09-20 17:23:36 +080010961 osd_hw.reg[OSD_COLOR_MODE].update_func(i);
10962 if (!osd_hw.dim_layer[i]) {
10963 VSYNCOSD_WR_MPEG_REG(osd_reg->osd_dimm_ctrl,
Googler9398cc32022-12-02 17:21:52 +080010964 0x00000000);
Googler4f18c0c2022-09-20 17:23:36 +080010965 } else {
10966 u32 dimm_rgb = 0;
10967
10968 dimm_rgb =
10969 ((osd_hw.dim_color[i] & 0xff000000)
10970 >> 24) << 22;
10971 dimm_rgb |=
10972 ((osd_hw.dim_color[i] & 0xff0000)
10973 >> 16) << 12;
10974 dimm_rgb |=
10975 ((osd_hw.dim_color[i] & 0xff00)
10976 >> 8) << 2;
10977 VSYNCOSD_WR_MPEG_REG(osd_reg->osd_dimm_ctrl,
Googler9398cc32022-12-02 17:21:52 +080010978 0x40000000 | dimm_rgb);
10979 VSYNCOSD_WR_MPEG_REG_BITS
10980 (osd_reg->osd_ctrl_stat2, 0x1, 14, 1);
10981 VSYNCOSD_WR_MPEG_REG_BITS
10982 (osd_reg->osd_ctrl_stat2,
Googler4f18c0c2022-09-20 17:23:36 +080010983 osd_hw.dim_color[i] & 0xff, 6, 8);
10984 }
10985 osd_hw.reg[DISP_GEOMETRY].update_func(i);
10986 osd_hw.reg[OSD_GBL_ALPHA].update_func(i);
10987 osd_hw.reg[DISP_OSD_REVERSE].update_func(i);
Googler9726be62022-12-14 05:53:31 +000010988 osd_hw.reg[OSD_FREESCALE_COEF].update_func(i);
10989 osd_hw.reg[DISP_FREESCALE_ENABLE]
Googler4f18c0c2022-09-20 17:23:36 +080010990 .update_func(i);
Googler9726be62022-12-14 05:53:31 +000010991 if (osd_update_window_axis)
10992 osd_update_window_axis = false;
10993 if (idx >= COLOR_INDEX_32_BGRX &&
10994 idx <= COLOR_INDEX_32_XRGB)
10995 rgbx = true;
Googler9398cc32022-12-02 17:21:52 +080010996 if (osd_hw.premult_en[i] && !osd_hw.blend_bypass[i] &&
Googler9726be62022-12-14 05:53:31 +000010997 !rgbx)
Googler9398cc32022-12-02 17:21:52 +080010998 VSYNCOSD_WR_MPEG_REG_BITS
10999 (osd_reg->osd_mali_unpack_ctrl,
11000 0x1, 28, 1);
Googler0109c452022-10-13 17:50:39 +080011001 else
Googler9398cc32022-12-02 17:21:52 +080011002 VSYNCOSD_WR_MPEG_REG_BITS
11003 (osd_reg->osd_mali_unpack_ctrl,
11004 0x0, 28, 1);
Googler9726be62022-12-14 05:53:31 +000011005#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
11006 if (osd_hw.secure_enable[i]) {
11007 switch (i) {
11008 case 0:
11009 secure_src |= OSD1_INPUT_SECURE;
11010 break;
11011 case 1:
11012 secure_src |= OSD2_INPUT_SECURE;
11013 break;
11014 case 2:
11015 secure_src |= OSD3_INPUT_SECURE;
11016 break;
Googler9398cc32022-12-02 17:21:52 +080011017 case 3:
11018 secure_src |= OSD4_INPUT_SECURE;
11019 break;
Googler9726be62022-12-14 05:53:31 +000011020 }
11021 }
11022 if (secure_src && osd_hw.osd_afbcd[i].enable)
11023 secure_src |= MALI_AFBCD_SECURE;
11024 osd_hw.secure_src = secure_src;
11025#endif
Googler4f18c0c2022-09-20 17:23:36 +080011026 }
11027 osd_hw.reg[OSD_ENABLE].update_func(i);
11028 }
11029
Googler012a81c2022-09-15 14:55:24 +080011030 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +080011031 osd_mali_afbc_start(output_index);
Googler012a81c2022-09-15 14:55:24 +080011032
Googler9398cc32022-12-02 17:21:52 +080011033 set_blend_reg(blending);
11034 save_blend_reg(blending);
Googler9726be62022-12-14 05:53:31 +000011035#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
Googler9398cc32022-12-02 17:21:52 +080011036 secure_config(OSD_MODULE, secure_src, output_index);
Googler9726be62022-12-14 05:53:31 +000011037#endif
11038 /* append RDMA_DETECT_REG at last and detect if rdma missed some regs */
Googler4f18c0c2022-09-20 17:23:36 +080011039 rdma_dt_cnt++;
11040 VSYNCOSD_WR_MPEG_REG(RDMA_DETECT_REG, rdma_dt_cnt);
11041 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +000011042 line2 = get_exit_encp_line(VIU1);
11043 osd_log_dbg(MODULE_RENDER,
Googler9398cc32022-12-02 17:21:52 +080011044 "%s:encp line1=%d, line2=%d, total_line=%d\n",
11045 __func__, line1, line2, total_line);
11046 osd_wait_vsync_hw_viux(output_index);
Googler4f18c0c2022-09-20 17:23:36 +080011047 val = osd_reg_read(RDMA_DETECT_REG);
Googler9726be62022-12-14 05:53:31 +000011048 if (line2 < line1) {
11049 osd_hw.rdma_delayed_cnt3++;
11050 osd_log_dbg(MODULE_ENCP_STAT, "osd line stat %d,%d, rdma_delayed_cnt3=%d\n",
11051 line1, line2, osd_hw.rdma_delayed_cnt3);
11052 }
Googler4f18c0c2022-09-20 17:23:36 +080011053 /* if missed, need wait vsync */
Googler9398cc32022-12-02 17:21:52 +080011054 if (val != rdma_dt_cnt) {
11055 osd_wait_vsync_hw_viux(output_index);
Googler9726be62022-12-14 05:53:31 +000011056 osd_hw.rdma_delayed_cnt2++;
11057 osd_log_dbg(MODULE_ENCP_STAT, "osd line stat %d,%d val=0x%x, rdma_dt_cnt=0x%x\n",
11058 line1, line2, val, rdma_dt_cnt);
Googler4f18c0c2022-09-20 17:23:36 +080011059 }
11060 return 0;
11061}
11062
11063/* only one layer */
11064static void osd_setting_default_hwc(void)
11065{
11066 u32 blend_hsize, blend_vsize;
Googler9726be62022-12-14 05:53:31 +000011067 u32 blend2_premult_en = 3, din_premult_en = 0;
11068 u32 blend_din_en = 0x5;
Googler4f18c0c2022-09-20 17:23:36 +080011069 /* blend_din0 input to blend0 */
Googler9726be62022-12-14 05:53:31 +000011070 u32 din0_byp_blend = 0;
Googler4f18c0c2022-09-20 17:23:36 +080011071 /* blend1_dout to blend2 */
Googler9726be62022-12-14 05:53:31 +000011072 u32 din2_osd_sel = 0;
Googler4f18c0c2022-09-20 17:23:36 +080011073 /* blend1_din3 input to blend1 */
Googler9726be62022-12-14 05:53:31 +000011074 u32 din3_osd_sel = 0;
11075 u32 din_reoder_sel = 0x4441;
Googler4f18c0c2022-09-20 17:23:36 +080011076 u32 postbld_src3_sel = 3, postbld_src4_sel = 0;
11077 u32 postbld_osd1_premult = 0, postbld_osd2_premult = 0;
11078
Googler9398cc32022-12-02 17:21:52 +080011079 osd_log_dbg(MODULE_BASE, "%s\n", __func__);
11080 if (osd_dev_hw.t7_display)
11081 postbld_src3_sel = POSTBLD_OSD1_T7;
11082 else
11083 postbld_src3_sel = POSTBLD_OSD1;
Googler4f18c0c2022-09-20 17:23:36 +080011084 /* depend on din0_premult_en */
Googler9726be62022-12-14 05:53:31 +000011085 postbld_osd1_premult = 0;
Googler4f18c0c2022-09-20 17:23:36 +080011086 /* depend on din_premult_en bit 4 */
11087 postbld_osd2_premult = 0;
11088 /* osd blend ctrl */
11089 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_CTRL,
Googler9398cc32022-12-02 17:21:52 +080011090 4 << 29 |
11091 blend2_premult_en << 27 |
11092 din0_byp_blend << 26 |
11093 din2_osd_sel << 25 |
11094 din3_osd_sel << 24 |
11095 blend_din_en << 20 |
11096 din_premult_en << 16 |
11097 din_reoder_sel);
Googler4f18c0c2022-09-20 17:23:36 +080011098 /* vpp osd1 blend ctrl */
11099 VSYNCOSD_WR_MPEG_REG(OSD1_BLEND_SRC_CTRL,
Googler9398cc32022-12-02 17:21:52 +080011100 (0 & 0xf) << 0 |
11101 (0 & 0x1) << 4 |
11102 (postbld_src3_sel & 0xf) << 8 |
11103 (postbld_osd1_premult & 0x1) << 16 |
11104 (1 & 0x1) << 20);
Googler4f18c0c2022-09-20 17:23:36 +080011105 /* vpp osd2 blend ctrl */
11106 if (!enable_vd_zorder)
Googler9398cc32022-12-02 17:21:52 +080011107 VSYNCOSD_WR_MPEG_REG(OSD2_BLEND_SRC_CTRL,
11108 (0 & 0xf) << 0 |
11109 (0 & 0x1) << 4 |
11110 (postbld_src4_sel & 0xf) << 8 |
11111 (postbld_osd2_premult & 0x1) << 16 |
11112 (1 & 0x1) << 20);
Googler4f18c0c2022-09-20 17:23:36 +080011113
11114 /* Do later: different format select different dummy_data */
11115 /* used default dummy data */
11116 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_DUMMY_DATA0,
Googler9398cc32022-12-02 17:21:52 +080011117 0x80 << 16 |
11118 0x80 << 8 |
11119 0x80);
Googler4f18c0c2022-09-20 17:23:36 +080011120 /* used default dummy alpha data */
11121 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_DUMMY_ALPHA,
Googler9398cc32022-12-02 17:21:52 +080011122 0x0 << 20 |
11123 0x0 << 11 |
11124 0x0);
Googler4f18c0c2022-09-20 17:23:36 +080011125
11126 blend_hsize = osd_hw.disp_info[VIU1].background_w;
11127 blend_vsize = osd_hw.disp_info[VIU1].background_h;
11128
11129 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE,
Googler9398cc32022-12-02 17:21:52 +080011130 blend_vsize << 16 |
11131 blend_hsize);
Googler4f18c0c2022-09-20 17:23:36 +080011132 VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE,
Googler9398cc32022-12-02 17:21:52 +080011133 blend_vsize << 16 |
11134 blend_hsize);
Googler9726be62022-12-14 05:53:31 +000011135 /* hdr input size should set to osd blend0 output size */
11136 VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE,
Googler9398cc32022-12-02 17:21:52 +080011137 blend_vsize << 16 |
11138 blend_hsize);
11139 if (osd_dev_hw.has_multi_vpp) {
11140 osd_set_vpp_path(VPP_OSD3, get_output_device_id(OSD3));
11141 osd_set_vpp_path(VPP_OSD4, get_output_device_id(OSD4));
11142 set_osd_hdr_size_in(VPP_OSD1,
11143 blend_hsize,
11144 blend_vsize);
11145 /* vpp input mux */
11146 VSYNCOSD_WR_MPEG_REG_BITS(OSD_PATH_MISC_CTRL, VPP_OSD1, 16, 4);
11147 }
Googler4f18c0c2022-09-20 17:23:36 +080011148}
11149
11150static bool set_old_hwc_freescale(u32 index)
11151{
11152 u32 x_start, x_end, y_start, y_end, height_dst, height_src;
11153
11154 if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
11155 x_start = osd_hw.vinfo_width[VIU1]
11156 - osd_hw.free_dst_data[index].x_end - 1;
11157 y_start = osd_hw.vinfo_height[VIU1]
11158 - osd_hw.free_dst_data[index].y_end - 1;
11159 x_end = osd_hw.vinfo_width[VIU1]
11160 - osd_hw.free_dst_data[index].x_start - 1;
11161 y_end = osd_hw.vinfo_height[VIU1]
11162 - osd_hw.free_dst_data[index].y_start - 1;
11163 osd_hw.free_dst_data[index].x_start = x_start;
11164 osd_hw.free_dst_data[index].y_start = y_start;
11165 osd_hw.free_dst_data[index].x_end = x_end;
11166 osd_hw.free_dst_data[index].y_end = y_end;
11167 } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
11168 x_start = osd_hw.vinfo_width[VIU1]
11169 - osd_hw.free_dst_data[index].x_end - 1;
11170 x_end = osd_hw.vinfo_width[VIU1]
11171 - osd_hw.free_dst_data[index].x_start - 1;
11172 osd_hw.free_dst_data[index].x_start = x_start;
11173 osd_hw.free_dst_data[index].x_end = x_end;
11174 } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
11175 y_start = osd_hw.vinfo_height[VIU1]
11176 - osd_hw.free_dst_data[index].y_end - 1;
11177 y_end = osd_hw.vinfo_height[VIU1]
11178 - osd_hw.free_dst_data[index].y_start - 1;
11179 osd_hw.free_dst_data[index].y_start = y_start;
11180 osd_hw.free_dst_data[index].y_end = y_end;
11181 }
11182 /* set dummy_data alpha */
11183 height_dst = osd_hw.free_dst_data[index].y_end -
11184 osd_hw.free_dst_data[index].y_start + 1;
11185 height_src = osd_hw.free_src_data[index].y_end -
11186 osd_hw.free_src_data[index].y_start + 1;
Googler9726be62022-12-14 05:53:31 +000011187 if (height_dst != height_src &&
11188 osd_hw.free_dst_data[index].y_end <
11189 osd_hw.vinfo_height[VIU1] - 1)
Googler4f18c0c2022-09-20 17:23:36 +080011190 osd_set_dummy_data(index, 0);
11191 else
11192 osd_set_dummy_data(index, 0xff);
11193
Googler9398cc32022-12-02 17:21:52 +080011194 if ((memcmp(&osd_hw.free_src_data[index],
11195 &osd_hw.free_src_data_backup[index],
11196 sizeof(struct pandata_s)) != 0) ||
11197 memcmp(&osd_hw.free_dst_data[index],
11198 &osd_hw.free_dst_data_backup[index],
11199 sizeof(struct pandata_s)) != 0) {
Googler4f18c0c2022-09-20 17:23:36 +080011200 memcpy(&osd_hw.free_src_data_backup[index],
Googler9398cc32022-12-02 17:21:52 +080011201 &osd_hw.free_src_data[index],
11202 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +080011203 memcpy(&osd_hw.free_dst_data_backup[index],
Googler9398cc32022-12-02 17:21:52 +080011204 &osd_hw.free_dst_data[index],
11205 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +080011206 return true;
Googler9398cc32022-12-02 17:21:52 +080011207 } else {
Googler4f18c0c2022-09-20 17:23:36 +080011208 return false;
Googler9398cc32022-12-02 17:21:52 +080011209 }
Googler4f18c0c2022-09-20 17:23:36 +080011210}
11211
11212static void osd_setting_old_hwc(void)
11213{
Googler9726be62022-12-14 05:53:31 +000011214 int index = OSD1, output_index = VIU1;
Googler4f18c0c2022-09-20 17:23:36 +080011215 bool freescale_update = false;
11216 static u32 osd_enable;
11217
11218 spin_lock_irqsave(&osd_lock, lock_flags);
Googler9398cc32022-12-02 17:21:52 +080011219 if (!osd_hw.osd_afbcd[index].enable) {
11220 if (osd_hw.osd_meson_dev.mif_linear)
11221 osd_update_mif_linear_addr(index);
11222 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
11223 else
11224 canvas_config(osd_hw.fb_gem[index].canvas_idx,
11225 osd_hw.fb_gem[index].addr,
11226 CANVAS_ALIGNED(osd_hw.fb_gem[index].width),
11227 osd_hw.fb_gem[index].height,
11228 CANVAS_ADDR_NOWRAP,
11229 CANVAS_BLKMODE_LINEAR);
11230 #endif
11231 }
Googler4f18c0c2022-09-20 17:23:36 +080011232 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
11233 freescale_update = set_old_hwc_freescale(index);
11234 /* geometry and freescale need update with ioctl */
11235 osd_hw.reg[DISP_GEOMETRY].update_func(index);
11236 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
Googler9398cc32022-12-02 17:21:52 +080011237 if ((osd_hw.free_scale_enable[index] &&
11238 osd_update_window_axis) ||
11239 freescale_update) {
Googler9726be62022-12-14 05:53:31 +000011240 if (!osd_hw.osd_display_debug[output_index]) {
Googler4f18c0c2022-09-20 17:23:36 +080011241 osd_set_scan_mode(index);
11242 osd_hw.reg[OSD_FREESCALE_COEF]
11243 .update_func(index);
11244 osd_hw.reg[DISP_FREESCALE_ENABLE]
11245 .update_func(index);
11246 }
11247 osd_update_window_axis = false;
11248 }
Googler9398cc32022-12-02 17:21:52 +080011249 if (osd_enable != osd_hw.enable[index] &&
11250 !osd_hw.osd_display_debug[output_index] &&
11251 !suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +080011252 osd_hw.reg[OSD_ENABLE]
11253 .update_func(index);
11254 osd_enable = osd_hw.enable[index];
11255 }
11256 spin_unlock_irqrestore(&osd_lock, lock_flags);
Googler9726be62022-12-14 05:53:31 +000011257 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +080011258}
11259
Googler9398cc32022-12-02 17:21:52 +080011260static struct hw_vppx_blend_reg_s vpp_topx_blend_reg_array[VPU_VPP_MAX] = {
11261 {/* reserved regs */},
11262 {
11263 VPP1_BLD_DIN1_HSCOPE,
11264 VPP1_BLD_DIN1_VSCOPE,
11265 VPP1_BLD_OUT_SIZE,
11266 VPP1_BLD_CTRL,
11267 VPP1_BLEND_BLEND_DUMMY_DATA,
11268 VPP1_BLEND_DUMMY_ALPHA,
11269 },
11270 {
11271 VPP2_BLD_DIN1_HSCOPE,
11272 VPP2_BLD_DIN1_VSCOPE,
11273 VPP2_BLD_OUT_SIZE,
11274 VPP2_BLD_CTRL,
11275 VPP2_BLEND_BLEND_DUMMY_DATA,
11276 VPP2_BLEND_DUMMY_ALPHA,
11277 },
11278};
11279
11280static void osd_setting_viux(u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +080011281{
Googler9398cc32022-12-02 17:21:52 +080011282 int index = 0, i;
11283 struct hw_osd_reg_s *osd_reg = NULL;
Googler9726be62022-12-14 05:53:31 +000011284 static int count;
Googler9398cc32022-12-02 17:21:52 +080011285 struct hw_vppx_blend_reg_s *vppx_blend_reg = NULL;
11286 struct vinfo_s *vinfo = NULL;
11287 u32 vpp_blend_ctrl = 0;
11288 /* 1:vd1 2:osd1 else :close */
11289 u32 bld_src2_sel = 2;
11290 u32 osd1_premult = 0;
11291 u32 blend_en = 1;
Googler4f18c0c2022-09-20 17:23:36 +080011292
Googler9398cc32022-12-02 17:21:52 +080011293 osd_log_dbg2(MODULE_RENDER, "### vpp_top%d display\n", output_index);
11294
11295 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) {
11296 if (validate_osd(i, output_index)) {
11297 index = i;
11298 break;
11299 }
Googler9726be62022-12-14 05:53:31 +000011300 }
Googler9398cc32022-12-02 17:21:52 +080011301
11302 osd_reg = &hw_osd_reg_array[index];
11303
11304 if (osd_dev_hw.t7_display) {
11305 u32 width, height;
11306 struct osd_rdma_fun_s *rdma_func = &osd_hw.osd_rdma_func[output_index];
11307 osd_rdma_rd_op rdma_rd = rdma_func->osd_rdma_rd;
11308 osd_rdma_wr_op rdma_wr = rdma_func->osd_rdma_wr;
11309 osd_rdma_wr_bits_op rdma_wr_bits = rdma_func->osd_rdma_wr_bits;
11310
11311 /* enable free_scale */
11312 if (osd_hw.pps_support[index]) {
11313 osd_hw.free_scale_enable[index] = 0x10001;
11314 osd_hw.free_scale[index].h_enable = 1;
11315 osd_hw.free_scale[index].v_enable = 1;
11316 osd_hw.free_scale_mode[index] = 1;
11317 } else {
11318 osd_hw.free_scale_enable[index] = 0x0;
11319 osd_hw.free_scale[index].h_enable = 0;
11320 osd_hw.free_scale[index].v_enable = 0;
11321 }
11322 osd_hw.free_src_data[index].x_start =
11323 osd_hw.src_data[index].x;
11324 osd_hw.free_src_data[index].x_end =
11325 osd_hw.src_data[index].x +
11326 osd_hw.src_data[index].w - 1;
11327 osd_hw.free_src_data[index].y_start =
11328 osd_hw.src_data[index].y;
11329 osd_hw.free_src_data[index].y_end =
11330 osd_hw.src_data[index].y +
11331 osd_hw.src_data[index].h - 1;
11332 if (osd_hw.osd_v_skip[index]) {
11333 osd_hw.free_src_data[index].y_end =
11334 (osd_hw.src_data[index].y +
11335 osd_hw.src_data[index].h) / 2 - 1;
11336 }
11337
11338 osd_hw.free_dst_data[index].x_start =
11339 osd_hw.dst_data[index].x;
11340 osd_hw.free_dst_data[index].y_start =
11341 osd_hw.dst_data[index].y;
11342 width = osd_hw.dst_data[index].w;
11343 height = osd_hw.dst_data[index].h;
11344 if (osd_hw.field_out_en[output_index]) {
11345 height = height >> 1;
11346 osd_hw.free_dst_data[index].y_start >>= 1;
11347 }
11348
11349 osd_hw.free_dst_data[index].x_end =
11350 osd_hw.free_dst_data[index].x_start +
11351 width - 1;
11352 osd_hw.free_dst_data[index].y_end =
11353 osd_hw.free_dst_data[index].y_start +
11354 height - 1;
11355
11356 if (osd_hw.enable[index]) {
11357 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
11358 enum color_index_e idx =
11359 osd_hw.color_info[index]->color_index;
11360 bool rgbx = false;
11361
11362 /* update = is_freescale_para_changed(i); */
11363 if (!osd_hw.osd_afbcd[index].enable) {
11364 if (osd_hw.osd_meson_dev.mif_linear)
11365 osd_update_mif_linear_addr(index);
11366 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
11367 else
11368 canvas_config(osd_hw.fb_gem[index].canvas_idx,
11369 osd_hw.fb_gem[index].addr,
11370 CANVAS_ALIGNED
11371 (osd_hw.fb_gem[index].width),
11372 osd_hw.fb_gem[index].height,
11373 CANVAS_ADDR_NOWRAP,
11374 CANVAS_BLKMODE_LINEAR);
11375 #endif
11376 }
11377 osd_set_scan_mode(index);
11378 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
11379 if (!osd_hw.dim_layer[index]) {
11380 rdma_wr(osd_reg->osd_dimm_ctrl, 0x00000000);
11381 } else {
11382 u32 dimm_rgb = 0;
11383
11384 dimm_rgb =
11385 ((osd_hw.dim_color[index] & 0xff000000)
11386 >> 24) << 22;
11387 dimm_rgb |=
11388 ((osd_hw.dim_color[index] & 0xff0000)
11389 >> 16) << 12;
11390 dimm_rgb |=
11391 ((osd_hw.dim_color[index] & 0xff00)
11392 >> 8) << 2;
11393 rdma_wr(osd_reg->osd_dimm_ctrl,
11394 0x40000000 | dimm_rgb);
11395 rdma_wr_bits(osd_reg->osd_ctrl_stat2,
11396 0x1, 14, 1);
11397 rdma_wr_bits(osd_reg->osd_ctrl_stat2,
11398 osd_hw.dim_color[index] & 0xff,
11399 6, 8);
11400 }
11401
11402 osd_hw.reg[DISP_GEOMETRY].update_func(index);
11403 osd_hw.reg[OSD_GBL_ALPHA].update_func(index);
11404 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
11405 osd_hw.reg[OSD_FREESCALE_COEF].update_func(index);
11406 osd_hw.reg[DISP_FREESCALE_ENABLE]
11407 .update_func(index);
11408
11409 if (idx >= COLOR_INDEX_32_BGRX &&
11410 idx <= COLOR_INDEX_32_XRGB)
11411 rgbx = true;
11412 if (osd_hw.premult_en[index] && !rgbx)
11413 rdma_wr_bits(osd_reg->osd_mali_unpack_ctrl,
11414 0x1, 28, 1);
11415 else
11416 rdma_wr_bits(osd_reg->osd_mali_unpack_ctrl,
11417 0x0, 28, 1);
11418 }
11419
11420 /* bypass free_scaler & osd_blend */
11421 if (osd_dev_hw.path_ctrl_independ) {
11422 rdma_wr_bits(VIU_OSD1_PATH_CTRL + index, 0x1, 4, 1);
11423 rdma_wr_bits(VIU_OSD1_PATH_CTRL + index, 0x1, 0, 1);
11424 } else {
11425 rdma_wr_bits(VPP_OSD1_SCALE_CTRL + index, 0x7, 0, 3);
11426 }
11427
11428 /* hdr in size */
11429 set_osd_hdr_size_in(index, width, height);
11430
11431 /* vpp_top input mux */
11432 rdma_wr_bits(OSD_PATH_MISC_CTRL, index + VPP_OSD1,
11433 index * 4 + 16, 8);
11434
11435 /* to vpp_topx */
11436 vppx_blend_reg = &vpp_topx_blend_reg_array[output_index];
11437 osd_set_vpp_path(index + VPP_OSD1, output_index);
11438
11439 rdma_wr(vppx_blend_reg->vpp_bld_din1_hscope,
11440 (osd_hw.free_dst_data[index].x_start << 16) |
11441 osd_hw.free_dst_data[index].x_end);
11442
11443 rdma_wr(vppx_blend_reg->vpp_bld_din1_vscope,
11444 (osd_hw.free_dst_data[index].y_start << 16) |
11445 osd_hw.free_dst_data[index].y_end);
11446
11447 if (osd_hw.enable[index] == ENABLE)
11448 bld_src2_sel = 2;
11449 else
11450 bld_src2_sel = 0;
11451 //vpp_blend_ctrl = rdma_rd(vppx_blend_reg->vpp_bld_ctrl);
11452 vpp_blend_ctrl |= bld_src2_sel << 4 |
11453 osd1_premult << 17 |
11454 blend_en << 31;
11455 if (output_index == VPU_VPP1)
11456 osd_vpp1_bld_ctrl = vpp_blend_ctrl |
11457 osd_vpp_bld_ctrl_update_mask;
11458 else if (output_index == VPU_VPP2)
11459 osd_vpp2_bld_ctrl = vpp_blend_ctrl |
11460 osd_vpp_bld_ctrl_update_mask;
11461
11462 //rdma_wr(vppx_blend_reg->vpp_bld_ctrl, vpp_blend_ctrl);
11463 switch (output_index) {
11464 case VPU_VPP0:
11465 #ifdef CONFIG_AMLOGIC_VOUT_SERVE
11466 vinfo = get_current_vinfo();
11467 #endif
11468 break;
11469 case VPU_VPP1:
11470 #ifdef CONFIG_AMLOGIC_VOUT2_SERVE
11471 vinfo = get_current_vinfo2();
11472 #endif
11473 break;
11474 case VPU_VPP2:
11475 #ifdef CONFIG_AMLOGIC_VOUT3_SERVE
11476 vinfo = get_current_vinfo3();
11477 #endif
11478 break;
11479 default:
11480 osd_log_err("osd%d, vpp_top%x index error\n", index, output_index);
11481 break;
11482 }
11483
11484 if (vinfo)
11485 osd_log_dbg2(MODULE_RENDER, "screen%d, W:%d H:%d\n",
11486 output_index, vinfo->width,
11487 vinfo->field_height);
11488 if (vinfo) {
11489 u32 read_value =
11490 rdma_rd(vppx_blend_reg->vpp_bld_out_size);
11491
11492 if (((vinfo->field_height << 16) | vinfo->width) !=
11493 read_value)
11494 rdma_wr(vppx_blend_reg->vpp_bld_out_size,
11495 ((vinfo->field_height << 16) |
11496 vinfo->width));
11497 } else {
11498 osd_log_err("%s, %d current vinfo NULL\n",
11499 __func__, __LINE__);
11500 }
11501
11502 osd_hw.reg[OSD_ENABLE].update_func(index);
11503
11504 if (osd_hw.hw_rdma_en)
11505 osd_mali_afbc_start(output_index);
11506
Googler9726be62022-12-14 05:53:31 +000011507 } else {
Googler9398cc32022-12-02 17:21:52 +080011508 count++;
11509 if (!osd_hw.osd_afbcd[index].enable)
11510 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
11511 canvas_config(osd_hw.fb_gem[index].canvas_idx,
11512 osd_hw.fb_gem[index].addr,
11513 CANVAS_ALIGNED(osd_hw.fb_gem[index].width),
11514 osd_hw.fb_gem[index].height,
11515 CANVAS_ADDR_NOWRAP,
11516 CANVAS_BLKMODE_LINEAR);
11517 #endif
11518 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
11519 if (count == 1) {
11520 /* geometry and freescale need update with ioctl */
11521 osd_hw.reg[DISP_GEOMETRY].update_func(index);
11522 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
11523 if (!osd_hw.osd_display_debug[output_index])
11524 osd_hw.reg[OSD_ENABLE]
11525 .update_func(index);
11526 }
11527 if (!osd_hw.dim_layer[index]) {
11528 VSYNCOSD_WR_MPEG_REG(osd_reg->osd_dimm_ctrl,
11529 0x00000000);
11530 } else {
11531 u32 dimm_rgb = 0;
Googler9726be62022-12-14 05:53:31 +000011532
Googler9398cc32022-12-02 17:21:52 +080011533 dimm_rgb =
11534 ((osd_hw.dim_color[index] & 0xff000000)
11535 >> 24) << 22;
11536 dimm_rgb |=
11537 ((osd_hw.dim_color[index] & 0xff0000)
11538 >> 16) << 12;
11539 dimm_rgb |=
11540 ((osd_hw.dim_color[index] & 0xff00)
11541 >> 8) << 2;
11542 VSYNCOSD_WR_MPEG_REG(osd_reg->osd_dimm_ctrl,
11543 0x40000000 | dimm_rgb);
11544 VSYNCOSD_WR_MPEG_REG_BITS(osd_reg->osd_ctrl_stat2, 0x1, 14, 1);
11545 VSYNCOSD_WR_MPEG_REG_BITS(osd_reg->osd_ctrl_stat2,
11546 osd_hw.dim_color[index] & 0xff, 6, 8);
11547 }
Googler9726be62022-12-14 05:53:31 +000011548 }
Googler9398cc32022-12-02 17:21:52 +080011549 osd_wait_vsync_hw_viux(output_index);
Googler4f18c0c2022-09-20 17:23:36 +080011550}
11551
Googler4f18c0c2022-09-20 17:23:36 +080011552int osd_setting_blend(u32 output_index)
11553{
11554 int ret;
Googler9398cc32022-12-02 17:21:52 +080011555 int start_index = 0;
11556 int osd_count = 0;
Googler4f18c0c2022-09-20 17:23:36 +080011557
Googler9398cc32022-12-02 17:21:52 +080011558 if (output_index == VIU1) {
11559 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
11560 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL)
11561 osd_count = 1;
11562 start_index = 0;
11563 } else if (output_index == VIU2) {
11564 if (osd_dev_hw.t7_display) {
11565 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
11566 start_index = 0;
11567 } else {
11568 start_index = osd_hw.osd_meson_dev.viu2_index;
11569 osd_count = start_index + 1;
11570 }
11571 }
11572
11573#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
11574 check_and_reverse_axis(start_index, osd_count, output_index);
11575#endif
11576 if (osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE) {
Googler4f18c0c2022-09-20 17:23:36 +080011577 osd_setting_old_hwc();
Googler9398cc32022-12-02 17:21:52 +080011578 } else {
Googler4f18c0c2022-09-20 17:23:36 +080011579 if (osd_hw.hwc_enable[output_index]) {
11580 if (output_index == VIU1) {
11581 ret = osd_setting_order(output_index);
11582 if (ret < 0)
11583 return -1;
11584 } else if (output_index == VIU2) {
Googler9398cc32022-12-02 17:21:52 +080011585 osd_setting_viux(VIU2);
11586 } else if (output_index == VIU3) {
11587 osd_setting_viux(VIU3);
Googler4f18c0c2022-09-20 17:23:36 +080011588 }
11589 } else {
11590 osd_setting_default_hwc();
11591 }
11592 }
11593 return 0;
11594}
11595
Googler9398cc32022-12-02 17:21:52 +080011596void osd_mali_afbc_start(u32 output_index)
Googler4f18c0c2022-09-20 17:23:36 +080011597{
11598 int i, osd_count, afbc_enable = 0;
Googler9398cc32022-12-02 17:21:52 +080011599 struct hw_osd_reg_s *osd_reg;
11600
11601 struct osd_rdma_fun_s *rdma_func = &osd_hw.osd_rdma_func[output_index];
11602 osd_rdma_wr_op rdma_wr = rdma_func->osd_rdma_wr;
Googler4f18c0c2022-09-20 17:23:36 +080011603
11604 osd_count = osd_hw.osd_meson_dev.osd_count;
11605 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) {
Googler9398cc32022-12-02 17:21:52 +080011606 int afbc0_start = 0;
11607
Googler4f18c0c2022-09-20 17:23:36 +080011608 for (i = 0; i < osd_count; i++) {
Googler9398cc32022-12-02 17:21:52 +080011609 osd_reg = &hw_osd_reg_array[i];
11610 if (osd_hw.osd_afbcd[i].afbc_start)
Googler4f18c0c2022-09-20 17:23:36 +080011611 /* enable mali afbc */
11612 afbc_enable |= (1 << i);
Googler9398cc32022-12-02 17:21:52 +080011613
11614 if (osd_dev_hw.multi_afbc_core && osd_hw.osd_afbcd[i].afbc_start) {
11615 if (!validate_osd(i, output_index))
11616 continue;
11617
11618 if (i == 1 && afbc0_start)
11619 continue;
11620
11621 rdma_wr(osd_reg->vpu_mafbc_command,
11622 (osd_hw.afbc_use_latch ?
11623 2 : 1));
11624 osd_log_dbg2(MODULE_BASE, "AFBC osd%d start command\n", i);
11625 if (i == 0)
11626 afbc0_start = 1;
Googler4f18c0c2022-09-20 17:23:36 +080011627 }
11628 }
Googler9398cc32022-12-02 17:21:52 +080011629 if (!osd_dev_hw.multi_afbc_core && afbc_enable)
11630 VSYNCOSD_WR_MPEG_REG(VPU_MAFBC_COMMAND,
11631 (osd_hw.afbc_use_latch ?
11632 2 : 1));
Googler4f18c0c2022-09-20 17:23:36 +080011633 }
11634}
11635
Googler4f18c0c2022-09-20 17:23:36 +080011636static void osd_basic_update_disp_geometry(u32 index)
11637{
11638 struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
11639 u32 data32;
11640 u32 buffer_w, buffer_h;
Googler9398cc32022-12-02 17:21:52 +080011641 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +080011642
11643 data32 = (osd_hw.dispdata[index].x_start & 0xfff)
11644 | (osd_hw.dispdata[index].x_end & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011645 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11646 (osd_reg->osd_blk0_cfg_w3, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011647 if (osd_hw.scan_mode[index] == SCAN_MODE_INTERLACE)
11648 data32 = ((osd_hw.dispdata[index].y_start >> 1) & 0xfff)
11649 | ((((osd_hw.dispdata[index].y_end + 1)
11650 >> 1) - 1) & 0xfff) << 16;
11651 else
11652 data32 = (osd_hw.dispdata[index].y_start & 0xfff)
11653 | (osd_hw.dispdata[index].y_end
11654 & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011655 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11656 (osd_reg->osd_blk0_cfg_w4,
11657 data32);
Googler4f18c0c2022-09-20 17:23:36 +080011658
11659 if (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) {
11660 if (osd_hw.osd_afbcd[index].enable) {
11661 u64 headr_addr, out_addr;
11662
11663 /* set frame addr in linear: out_addr_id */
11664 headr_addr = osd_hw.osd_afbcd[index].phy_addr;
Googler9398cc32022-12-02 17:21:52 +080011665 /* mali afbc out ram addr = osd addr */
Googler4f18c0c2022-09-20 17:23:36 +080011666 out_addr = ((u64)osd_hw.osd_afbcd[index].out_addr_id)
11667 << 24;
11668 /* 0:canvas_araddr
11669 * 1:linear_araddr
11670 */
Googler9398cc32022-12-02 17:21:52 +080011671 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11672 (osd_reg->osd_ctrl_stat,
11673 0x1, 2, 1);
11674 if (osd_dev_hw.has_8G_addr)
11675 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11676 (osd_reg->osd_blk1_cfg_w4,
11677 out_addr >> 4);
11678 else
11679 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11680 (osd_reg->osd_blk1_cfg_w4,
11681 out_addr);
Googler4f18c0c2022-09-20 17:23:36 +080011682 /* unpac mali src */
Googler9398cc32022-12-02 17:21:52 +080011683 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11684 (osd_reg->osd_mali_unpack_ctrl,
11685 0x1, 31, 1);
Googler4f18c0c2022-09-20 17:23:36 +080011686
Googler9398cc32022-12-02 17:21:52 +080011687 /* osd switch to mali */
11688 if (osd_dev_hw.multi_afbc_core) {
11689 if (osd_dev_hw.path_ctrl_independ) {
11690 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11691 (osd_reg->mali_afbcd_top_ctrl,
11692 0x1, 31, 1);
11693 } else {
11694 if (index == OSD1)
11695 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11696 (osd_reg->mali_afbcd_top_ctrl,
11697 0x1, 16, 1);
11698 else
11699 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11700 (osd_reg->mali_afbcd_top_ctrl,
11701 0x1, 21, 1);
11702 }
11703 } else {
11704 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11705 (OSD_PATH_MISC_CTRL,
11706 0x01, (index + 4), 1);
11707 }
Googler4f18c0c2022-09-20 17:23:36 +080011708 /* read from mali afbd decoder */
Googler9398cc32022-12-02 17:21:52 +080011709 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11710 (osd_reg->osd_blk0_cfg_w0,
11711 0x1, 30, 1);
Googler4f18c0c2022-09-20 17:23:36 +080011712
Googler9398cc32022-12-02 17:21:52 +080011713 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11714 (osd_reg->afbc_header_buf_addr_low_s,
Googler4f18c0c2022-09-20 17:23:36 +080011715 headr_addr & 0xffffffff);
Googler9398cc32022-12-02 17:21:52 +080011716 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11717 (osd_reg->afbc_header_buf_addr_high_s,
Googler4f18c0c2022-09-20 17:23:36 +080011718 (headr_addr >> 32) & 0xffffffff);
Googler9398cc32022-12-02 17:21:52 +080011719 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11720 (osd_reg->afbc_buffer_width_s,
Googler4f18c0c2022-09-20 17:23:36 +080011721 osd_hw.osd_afbcd[index].frame_width);
Googler9398cc32022-12-02 17:21:52 +080011722 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11723 (osd_reg->afbc_buffer_hight_s,
Googler4f18c0c2022-09-20 17:23:36 +080011724 osd_hw.osd_afbcd[index].frame_height);
Googler9398cc32022-12-02 17:21:52 +080011725 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11726 (osd_reg->afbc_output_buf_addr_low_s,
Googler4f18c0c2022-09-20 17:23:36 +080011727 out_addr & 0xffffffff);
Googler9398cc32022-12-02 17:21:52 +080011728 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11729 (osd_reg->afbc_output_buf_addr_high_s,
Googler4f18c0c2022-09-20 17:23:36 +080011730 (out_addr >> 32) & 0xffffffff);
11731 if (osd_hw.osd_afbcd[index].enable) {
Googler9398cc32022-12-02 17:21:52 +080011732 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11733 (osd_reg->afbc_boundings_box_x_start_s,
Googler4f18c0c2022-09-20 17:23:36 +080011734 osd_hw.src_data[index].x);
Googler9398cc32022-12-02 17:21:52 +080011735 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11736 (osd_reg->afbc_boundings_box_x_end_s,
Googler4f18c0c2022-09-20 17:23:36 +080011737 osd_hw.src_data[index].x +
11738 osd_hw.src_data[index].w - 1);
Googler9398cc32022-12-02 17:21:52 +080011739 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11740 (osd_reg->afbc_boundings_box_y_start_s,
Googler4f18c0c2022-09-20 17:23:36 +080011741 osd_hw.src_data[index].y);
Googler9398cc32022-12-02 17:21:52 +080011742 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11743 (osd_reg->afbc_boundings_box_y_end_s,
Googler4f18c0c2022-09-20 17:23:36 +080011744 osd_hw.src_data[index].y +
11745 osd_hw.src_data[index].h - 1);
11746 }
11747 } else {
Googler9398cc32022-12-02 17:21:52 +080011748 /* osd switch to mali */
11749 if (osd_dev_hw.multi_afbc_core) {
11750 if (osd_dev_hw.path_ctrl_independ) {
11751 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11752 (osd_reg->mali_afbcd_top_ctrl,
11753 0x0, 31, 1);
11754 } else {
11755 if (index == OSD1)
11756 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11757 (osd_reg->mali_afbcd_top_ctrl,
11758 0x0, 16, 1);
11759 else
11760 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11761 (osd_reg->mali_afbcd_top_ctrl,
11762 0x0, 21, 1);
11763 }
11764 } else {
11765 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11766 (OSD_PATH_MISC_CTRL, 0x0, (index + 4), 1);
11767 }
Googler4f18c0c2022-09-20 17:23:36 +080011768 /* unpac normal src */
Googler9398cc32022-12-02 17:21:52 +080011769 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11770 (osd_reg->osd_mali_unpack_ctrl,
11771 0x0, 31, 1);
Googler4f18c0c2022-09-20 17:23:36 +080011772 /* read from ddr */
Googler9398cc32022-12-02 17:21:52 +080011773 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11774 (osd_reg->osd_blk0_cfg_w0, 0x0, 30, 1);
11775 /* use canvas addr should not clear for mif */
11776 if (!osd_hw.osd_meson_dev.mif_linear)
11777 osd_hw.osd_rdma_func[output_index].osd_rdma_wr_bits
11778 (osd_reg->osd_ctrl_stat, 0x0, 2, 1);
Googler4f18c0c2022-09-20 17:23:36 +080011779 }
11780 }
Googler9398cc32022-12-02 17:21:52 +080011781 if (osd_hw.free_scale_enable[index] &&
11782 osd_hw.free_src_data[index].x_end > 0 &&
11783 osd_hw.free_src_data[index].y_end > 0) {
Googler4f18c0c2022-09-20 17:23:36 +080011784 /* enable osd free scale */
11785 data32 = (osd_hw.free_src_data[index].x_start & 0x1fff) |
11786 (osd_hw.free_src_data[index].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011787 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11788 (osd_reg->osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011789 data32 = ((osd_hw.free_src_data[index].y_start
11790 + osd_hw.pandata[index].y_start) & 0x1fff)
11791 | ((osd_hw.free_src_data[index].y_end
11792 + osd_hw.pandata[index].y_start) & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011793 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11794 (osd_reg->osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011795 } else {
11796 /* normal mode */
11797 data32 = (osd_hw.pandata[index].x_start & 0x1fff)
11798 | (osd_hw.pandata[index].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011799 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11800 (osd_reg->osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011801 data32 = (osd_hw.pandata[index].y_start & 0x1fff)
11802 | (osd_hw.pandata[index].y_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011803 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11804 (osd_reg->osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011805 }
11806 data32 = (osd_hw.src_data[index].x & 0x1fff) |
11807 ((osd_hw.src_data[index].x +
11808 osd_hw.src_data[index].w - 1) & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011809 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11810 (hw_osd_reg_array[index].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011811 buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
11812 data32 = (osd_hw.src_data[index].y & 0x1fff)
11813 | ((osd_hw.src_data[index].y +
11814 osd_hw.src_data[index].h - 1) & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011815 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11816 (osd_reg->osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011817 buffer_h = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
Googler9398cc32022-12-02 17:21:52 +080011818 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
11819 (osd_reg->osd_ctrl_stat);
Googler4f18c0c2022-09-20 17:23:36 +080011820 data32 &= ~0x1ff008;//0x1ff00e;
11821 data32 |= osd_hw.gbl_alpha[index] << 12;
11822 /* data32 |= HW_OSD_BLOCK_ENABLE_0; */
Googler9398cc32022-12-02 17:21:52 +080011823 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
11824 (osd_reg->osd_ctrl_stat, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011825 remove_from_update_list(index, DISP_GEOMETRY);
11826}
11827
11828static void osd1_basic_update_disp_geometry(void)
11829{
11830 u32 data32;
11831 u32 buffer_w, buffer_h;
Googler9398cc32022-12-02 17:21:52 +080011832
Googler4f18c0c2022-09-20 17:23:36 +080011833 data32 = (osd_hw.dispdata[OSD1].x_start & 0xfff)
11834 | (osd_hw.dispdata[OSD1].x_end & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011835 VSYNCOSD_WR_MPEG_REG
11836 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w3, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011837 if (osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE)
11838 data32 = ((osd_hw.dispdata[OSD1].y_start >> 1) & 0xfff)
11839 | ((((osd_hw.dispdata[OSD1].y_end + 1)
11840 >> 1) - 1) & 0xfff) << 16;
11841 else
11842 data32 = (osd_hw.dispdata[OSD1].y_start & 0xfff)
11843 | (osd_hw.dispdata[OSD1].y_end
11844 & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011845 VSYNCOSD_WR_MPEG_REG
11846 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w4, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011847
11848 if (osd_hw.osd_afbcd[OSD1].enable)
11849 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_SIZE_IN,
Googler9398cc32022-12-02 17:21:52 +080011850 ((osd_hw.osd_afbcd[OSD1].frame_width
11851 & 0xffff) << 16) |
11852 ((osd_hw.osd_afbcd[OSD1].frame_height
11853 & 0xffff) << 0));
Googler4f18c0c2022-09-20 17:23:36 +080011854
11855 /* enable osd 2x scale */
11856 if (osd_hw.scale[OSD1].h_enable || osd_hw.scale[OSD1].v_enable) {
11857 osd1_2x_scale_update_geometry();
Googler9398cc32022-12-02 17:21:52 +080011858 data32 = VSYNCOSD_RD_MPEG_REG
11859 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w1);
Googler4f18c0c2022-09-20 17:23:36 +080011860 buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
Googler9398cc32022-12-02 17:21:52 +080011861 data32 = VSYNCOSD_RD_MPEG_REG
11862 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w2);
Googler4f18c0c2022-09-20 17:23:36 +080011863 buffer_h = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
Googler9398cc32022-12-02 17:21:52 +080011864 } else if (osd_hw.free_scale_enable[OSD1] &&
11865 (osd_hw.free_src_data[OSD1].x_end > 0) &&
11866 (osd_hw.free_src_data[OSD1].y_end > 0)) {
Googler4f18c0c2022-09-20 17:23:36 +080011867 /* enable osd free scale */
11868 data32 = (osd_hw.free_src_data[OSD1].x_start & 0x1fff) |
11869 (osd_hw.free_src_data[OSD1].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011870 VSYNCOSD_WR_MPEG_REG(hw_osd_reg_array[OSD1].osd_blk0_cfg_w1,
11871 data32);
Googler4f18c0c2022-09-20 17:23:36 +080011872 buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
11873 if (osd_hw.osd_afbcd[OSD1].enable) {
11874 data32 =
11875 (osd_hw.free_src_data[OSD1].x_end & 0x1fff) |
11876 (osd_hw.free_src_data[OSD1].x_start & 0x1fff)
11877 << 16;
11878 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_HSCOPE, data32);
11879 data32 =
11880 (osd_hw.free_src_data[OSD1].y_end & 0x1fff) |
11881 (osd_hw.free_src_data[OSD1].y_start & 0x1fff)
11882 << 16;
11883 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_VSCOPE, data32);
11884 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_HDR_PTR,
Googler9398cc32022-12-02 17:21:52 +080011885 osd_hw.osd_afbcd[OSD1].phy_addr
11886 >> 4);
Googler4f18c0c2022-09-20 17:23:36 +080011887 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_FRAME_PTR,
Googler9398cc32022-12-02 17:21:52 +080011888 osd_hw.osd_afbcd[OSD1].phy_addr
11889 >> 4);
Googler4f18c0c2022-09-20 17:23:36 +080011890 data32 = (0xe4 << 24) |
11891 (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff);
Googler9398cc32022-12-02 17:21:52 +080011892 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_CHROMA_PTR,
11893 data32);
Googler4f18c0c2022-09-20 17:23:36 +080011894 }
11895 data32 = ((osd_hw.free_src_data[OSD1].y_start
11896 + osd_hw.pandata[OSD1].y_start) & 0x1fff)
11897 | ((osd_hw.free_src_data[OSD1].y_end
11898 + osd_hw.pandata[OSD1].y_start) & 0x1fff) << 16;
11899 VSYNCOSD_WR_MPEG_REG(VIU_OSD1_BLK0_CFG_W2, data32);
11900 buffer_h = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
11901 } else {
11902 /* normal mode */
11903 data32 = (osd_hw.pandata[OSD1].x_start & 0x1fff)
11904 | (osd_hw.pandata[OSD1].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011905 VSYNCOSD_WR_MPEG_REG
11906 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011907 buffer_w = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
11908 if (osd_hw.osd_afbcd[OSD1].enable) {
11909 u32 virtual_y_start, virtual_y_end;
11910
11911 data32 = (osd_hw.pandata[OSD1].x_end & 0x1fff)
11912 | (osd_hw.pandata[OSD1].x_start & 0x1fff) << 16;
11913 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_HSCOPE, data32);
11914 virtual_y_start = osd_hw.pandata[OSD1].y_start %
11915 osd_hw.osd_afbcd[OSD1].frame_height;
11916 virtual_y_end = osd_hw.pandata[OSD1].y_end -
11917 osd_hw.pandata[OSD1].y_start + virtual_y_start;
11918 data32 = (virtual_y_end & 0x1fff) |
11919 (virtual_y_start & 0x1fff) << 16;
11920 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_PIXEL_VSCOPE, data32);
11921 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_HDR_PTR,
Googler9398cc32022-12-02 17:21:52 +080011922 osd_hw.osd_afbcd[OSD1].phy_addr
11923 >> 4);
Googler4f18c0c2022-09-20 17:23:36 +080011924 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_FRAME_PTR,
Googler9398cc32022-12-02 17:21:52 +080011925 osd_hw.osd_afbcd[OSD1].phy_addr
11926 >> 4);
Googler4f18c0c2022-09-20 17:23:36 +080011927 data32 = (0xe4 << 24) |
11928 (osd_hw.osd_afbcd[OSD1].phy_addr & 0xffffff);
Googler9398cc32022-12-02 17:21:52 +080011929 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_CHROMA_PTR,
11930 data32);
Googler4f18c0c2022-09-20 17:23:36 +080011931 }
11932 data32 = (osd_hw.pandata[OSD1].y_start & 0x1fff)
11933 | (osd_hw.pandata[OSD1].y_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011934 VSYNCOSD_WR_MPEG_REG
11935 (hw_osd_reg_array[OSD1].osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011936 buffer_h = ((data32 >> 16) & 0x1fff) - (data32 & 0x1fff) + 1;
11937 }
11938 if (osd_hw.osd_meson_dev.has_dolby_vision) {
Googler9398cc32022-12-02 17:21:52 +080011939 VSYNCOSD_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL1,
11940 ((buffer_w + 0x40) << 16)
11941 | (buffer_h + 0x80 + 0));
11942 VSYNCOSD_WR_MPEG_REG(DOLBY_CORE2A_SWAP_CTRL2,
11943 (buffer_w << 16) | (buffer_h + 0));
Googler4f18c0c2022-09-20 17:23:36 +080011944#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
11945 update_graphic_width_height(buffer_w, buffer_h);
11946#endif
11947 }
11948 if (osd_hw.osd_afbcd[OSD1].enable &&
Googler9398cc32022-12-02 17:21:52 +080011949 !osd_afbc_dec_enable &&
11950 osd_hw.osd_afbcd[OSD1].phy_addr != 0) {
Googler4f18c0c2022-09-20 17:23:36 +080011951 VSYNCOSD_WR_MPEG_REG(OSD1_AFBCD_ENABLE, 0x8100);
11952 osd_afbc_dec_enable = 1;
11953 }
Googler9398cc32022-12-02 17:21:52 +080011954 data32 = VSYNCOSD_RD_MPEG_REG
11955 (hw_osd_reg_array[OSD1].osd_ctrl_stat);
Googler4f18c0c2022-09-20 17:23:36 +080011956 data32 &= ~0x1ff00e;
11957 data32 |= osd_hw.gbl_alpha[OSD1] << 12;
11958 /* data32 |= HW_OSD_BLOCK_ENABLE_0; */
11959 VSYNCOSD_WR_MPEG_REG(hw_osd_reg_array[OSD1].osd_ctrl_stat, data32);
11960 remove_from_update_list(OSD1, DISP_GEOMETRY);
11961}
11962
Googler4f18c0c2022-09-20 17:23:36 +080011963static void osd2_update_disp_geometry(void)
11964{
11965 u32 data32;
11966
11967 data32 = (osd_hw.dispdata[OSD2].x_start & 0xfff)
11968 | (osd_hw.dispdata[OSD2].x_end & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011969 VSYNCOSD_WR_MPEG_REG
11970 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w3, data32);
11971 if (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE &&
11972 osd_hw.dispdata[OSD2].y_start >= 0)
Googler4f18c0c2022-09-20 17:23:36 +080011973 data32 = (osd_hw.dispdata[OSD2].y_start & 0xfff)
11974 | ((((osd_hw.dispdata[OSD2].y_end + 1
11975 - osd_hw.dispdata[OSD2].y_start) >> 1)
11976 + osd_hw.dispdata[OSD2].y_start - 1)
11977 & 0xfff) << 16;
11978 else
11979 data32 = (osd_hw.dispdata[OSD2].y_start & 0xfff)
11980 | (osd_hw.dispdata[OSD2].y_end & 0xfff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011981 VSYNCOSD_WR_MPEG_REG
11982 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w4, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011983 if (osd_hw.scale[OSD2].h_enable || osd_hw.scale[OSD2].v_enable) {
11984#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR)
11985 data32 = (osd_hw.pandata[OSD2].x_start & 0x1fff)
11986 | (osd_hw.pandata[OSD2].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011987 VSYNCOSD_WR_MPEG_REG
11988 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011989 data32 = (osd_hw.pandata[OSD2].y_start & 0x1fff)
11990 | (osd_hw.pandata[OSD2].y_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011991 VSYNCOSD_WR_MPEG_REG
11992 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011993#else
11994 data32 = (osd_hw.scaledata[OSD2].x_start & 0x1fff) |
11995 (osd_hw.scaledata[OSD2].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080011996 VSYNCOSD_WR_MPEG_REG
11997 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080011998 data32 = ((osd_hw.scaledata[OSD2].y_start
11999 + osd_hw.pandata[OSD2].y_start) & 0x1fff)
12000 | ((osd_hw.scaledata[OSD2].y_end
12001 + osd_hw.pandata[OSD2].y_start) & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012002 VSYNCOSD_WR_MPEG_REG
12003 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012004#endif
Googler9398cc32022-12-02 17:21:52 +080012005 } else if (osd_hw.free_scale_enable[OSD2] &&
12006 (osd_hw.free_src_data[OSD2].x_end > 0) &&
12007 (osd_hw.free_src_data[OSD2].y_end > 0)) {
Googler4f18c0c2022-09-20 17:23:36 +080012008 /* enable osd free scale */
12009 data32 = (osd_hw.free_src_data[OSD2].x_start & 0x1fff)
12010 | (osd_hw.free_src_data[OSD2].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012011 VSYNCOSD_WR_MPEG_REG
12012 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012013 data32 = ((osd_hw.free_src_data[OSD2].y_start
12014 + osd_hw.pandata[OSD2].y_start) & 0x1fff)
12015 | ((osd_hw.free_src_data[OSD2].y_end
12016 + osd_hw.pandata[OSD2].y_start) & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012017 VSYNCOSD_WR_MPEG_REG
12018 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012019 } else {
12020 data32 = (osd_hw.pandata[OSD2].x_start & 0x1fff)
12021 | (osd_hw.pandata[OSD2].x_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012022 VSYNCOSD_WR_MPEG_REG
12023 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012024 data32 = (osd_hw.pandata[OSD2].y_start & 0x1fff)
12025 | (osd_hw.pandata[OSD2].y_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012026 VSYNCOSD_WR_MPEG_REG
12027 (hw_osd_reg_array[OSD2].osd_blk0_cfg_w2, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012028 }
Googler9398cc32022-12-02 17:21:52 +080012029 data32 = VSYNCOSD_RD_MPEG_REG
12030 (hw_osd_reg_array[OSD2].osd_ctrl_stat);
Googler4f18c0c2022-09-20 17:23:36 +080012031 data32 &= ~0x1ff000;
12032 data32 |= osd_hw.gbl_alpha[OSD2] << 12;
12033 /* data32 |= HW_OSD_BLOCK_ENABLE_0; */
Googler9398cc32022-12-02 17:21:52 +080012034 VSYNCOSD_WR_MPEG_REG
12035 (hw_osd_reg_array[OSD2].osd_ctrl_stat, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012036 remove_from_update_list(OSD2, DISP_GEOMETRY);
12037}
12038
Googler4f18c0c2022-09-20 17:23:36 +080012039static void osd_update_disp_geometry(u32 index)
12040{
Googler9398cc32022-12-02 17:21:52 +080012041 if (osd_hw.block_mode[index] &&
12042 osd_hw.osd_meson_dev.cpu_id <= __MESON_CPU_MAJOR_ID_GXBB) {
12043 osd_log_info("%s: not support block mode\n", __func__);
Googler4f18c0c2022-09-20 17:23:36 +080012044 } else {
12045 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
12046 /* single block */
12047 if (index == OSD1)
12048 osd1_basic_update_disp_geometry();
12049 else if (index == OSD2)
12050 osd2_update_disp_geometry();
12051 } else {
12052 osd_basic_update_disp_geometry(index);
12053 }
12054 }
12055}
12056
Googler4f18c0c2022-09-20 17:23:36 +080012057static void osd_update_disp_3d_mode(u32 index)
12058{
12059 /*step 1 . set pan data */
12060 /* only called by vsync irq or rdma irq */
12061 u32 data32;
12062
12063 if (osd_hw.mode_3d[index].left_right == OSD_LEFT) {
12064 data32 = (osd_hw.mode_3d[index].l_start & 0x1fff)
12065 | (osd_hw.mode_3d[index].l_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012066 VSYNCOSD_IRQ_WR_MPEG_REG
12067 (hw_osd_reg_array[index].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012068 } else {
12069 data32 = (osd_hw.mode_3d[index].r_start & 0x1fff)
12070 | (osd_hw.mode_3d[index].r_end & 0x1fff) << 16;
Googler9398cc32022-12-02 17:21:52 +080012071 VSYNCOSD_IRQ_WR_MPEG_REG
12072 (hw_osd_reg_array[index].osd_blk0_cfg_w1, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012073 }
12074 osd_hw.mode_3d[index].left_right ^= 1;
12075}
12076
12077static void osd_update_fifo(u32 index)
12078{
12079 u32 data32;
Googler9398cc32022-12-02 17:21:52 +080012080 u32 output_index = get_output_device_id(index);
Googler4f18c0c2022-09-20 17:23:36 +080012081
Googler9398cc32022-12-02 17:21:52 +080012082 data32 = osd_hw.osd_rdma_func[output_index].osd_rdma_rd
12083 (hw_osd_reg_array[index].osd_fifo_ctrl_stat);
Googler9726be62022-12-14 05:53:31 +000012084 data32 |= osd_hw.urgent[index] & 1;
Googler9398cc32022-12-02 17:21:52 +080012085 osd_hw.osd_rdma_func[output_index].osd_rdma_wr
12086 (hw_osd_reg_array[index].osd_fifo_ctrl_stat, data32);
Googler4f18c0c2022-09-20 17:23:36 +080012087 remove_from_update_list(index, OSD_FIFO);
12088}
12089
12090void osd_init_scan_mode(void)
12091{
12092 unsigned int output_type = 0;
12093
12094 output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3;
12095 osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE;
12096 osd_hw.scan_mode[OSD2] = SCAN_MODE_PROGRESSIVE;
12097 osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE;
12098 switch (output_type) {
12099 case VOUT_ENCP:
12100 if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) {
12101 /* 1080i */
12102 osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE;
12103 osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
12104 osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE;
12105 }
12106 break;
12107 case VOUT_ENCI:
12108 if (osd_reg_read(ENCI_VIDEO_EN) & 1) {
12109 osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE;
12110 osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
12111 osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE;
12112 }
12113 break;
12114 }
12115}
12116
12117static int osd_extra_canvas_alloc(void)
12118{
12119 int osd_num = 2;
12120
12121 osd_extra_idx[0][0] = EXTERN1_CANVAS;
12122 osd_extra_idx[0][1] = EXTERN2_CANVAS;
Googler9398cc32022-12-02 17:21:52 +080012123#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler9726be62022-12-14 05:53:31 +000012124 osd_num = (osd_hw.osd_meson_dev.osd_count - 1) * 2;
Googler4f18c0c2022-09-20 17:23:36 +080012125 if (canvas_pool_alloc_canvas_table("osd_extra",
Googler9398cc32022-12-02 17:21:52 +080012126 &osd_extra_idx[1][0],
12127 osd_num,
12128 CANVAS_MAP_TYPE_1)) {
Googler4f18c0c2022-09-20 17:23:36 +080012129 osd_log_info("allocate osd extra canvas error.\n");
12130 return -1;
12131 }
Googler9398cc32022-12-02 17:21:52 +080012132#endif
Googler0109c452022-10-13 17:50:39 +080012133 return 0;
Googler38bda472022-08-19 10:07:08 -070012134}
Googler38bda472022-08-19 10:07:08 -070012135
Googler9726be62022-12-14 05:53:31 +000012136#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
12137/* kthread affinity set api */
12138static void affinity_set(unsigned long mask)
12139{
12140 int i;
12141
12142 for (i = 0; i < VIU_COUNT; i++) {
12143 if (buffer_toggle_thread[i])
12144 set_cpus_allowed_ptr(buffer_toggle_thread[i],
12145 (struct cpumask *)&mask);
12146 }
12147}
12148
12149static int affinity_set_task(void *data)
12150{
Googler9398cc32022-12-02 17:21:52 +080012151 int ret;
Googler9726be62022-12-14 05:53:31 +000012152 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1};
12153
12154 sched_setscheduler(current, SCHED_FIFO, &param);
12155 allow_signal(SIGTERM);
12156
12157 while (affinity_info.run_affinity_task) {
Googler9398cc32022-12-02 17:21:52 +080012158 ret = wait_for_completion_interruptible
12159 (&affinity_info.affinity_task_com);
Googler9726be62022-12-14 05:53:31 +000012160 msleep(200);
12161 affinity_set(affinity_info.affinity_mask);
12162 }
12163
12164 return 0;
12165}
12166
Googler9398cc32022-12-02 17:21:52 +080012167#ifdef CPU_NOTIFY
Googler9726be62022-12-14 05:53:31 +000012168static int cpu_switch_cb(struct notifier_block *nfb,
12169 unsigned long action, void *hcpu)
12170{
12171 int cpu;
12172 static int cpu_down_save;
12173 unsigned long _cpu_mask = *cpumask_bits(&affinity_info.cpu_mask);
12174
12175 if (action == CPU_POST_DEAD) {
12176 /* cpu core offline */
12177 cpu = (unsigned long)hcpu;
12178 cpu_down_save |= (1 << cpu);
12179 if (cpu_down_save == (_cpu_mask & (~1))) {
12180 /* other cpu all off, except cpu0 */
12181 affinity_info.affinity_mask = 1;
12182 complete(&affinity_info.affinity_task_com);
12183 }
12184 } else if (action == CPU_ONLINE) {
12185 /* cpu core online */
12186 cpu = (unsigned long)hcpu;
12187 cpu_down_save &= ~(1 << cpu);
12188 if (cpu_down_save != (_cpu_mask & (~1))) {
12189 affinity_info.affinity_mask = _cpu_mask & (~1);
12190 complete(&affinity_info.affinity_task_com);
12191 }
12192 }
12193 return 0;
12194}
Googler9398cc32022-12-02 17:21:52 +080012195#endif
Googler9726be62022-12-14 05:53:31 +000012196
12197static void affinity_set_init(void)
12198{
12199 struct task_struct *affinity_thread;
12200
12201 affinity_info.cpu_mask = *cpu_online_mask;
12202 init_completion(&affinity_info.affinity_task_com);
12203 affinity_info.run_affinity_task = 1;
Googler9398cc32022-12-02 17:21:52 +080012204 /* cpu_notifier(cpu_switch_cb, 0); */
Googler9726be62022-12-14 05:53:31 +000012205 affinity_thread = kthread_run(affinity_set_task,
12206 &affinity_info,
12207 "affinity_set_thread");
12208 if (!affinity_thread)
12209 pr_err("create affinity thread fail!\n");
12210}
12211#endif
12212
Googler9398cc32022-12-02 17:21:52 +080012213static void set_vpp_osd1_rgb2yuv(bool on)
Googler9726be62022-12-14 05:53:31 +000012214{
Googler9398cc32022-12-02 17:21:52 +080012215 int *m = NULL;
12216
12217 /* RGB -> 709 limit */
12218 m = RGB709_to_YUV709l_coeff;
12219
12220 /* VPP WRAP OSD3 matrix */
12221 osd_reg_write(VPP_OSD1_MATRIX_PRE_OFFSET0_1,
12222 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
12223 osd_reg_write(VPP_OSD1_MATRIX_PRE_OFFSET2,
12224 m[2] & 0xfff);
12225 osd_reg_write(VPP_OSD1_MATRIX_COEF00_01,
12226 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
12227 osd_reg_write(VPP_OSD1_MATRIX_COEF02_10,
12228 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
12229 osd_reg_write(VPP_OSD1_MATRIX_COEF11_12,
12230 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
12231 osd_reg_write(VPP_OSD1_MATRIX_COEF20_21,
12232 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
12233 osd_reg_write(VPP_OSD1_MATRIX_COEF22,
12234 m[11] & 0x1fff);
12235 osd_reg_write(VPP_OSD1_MATRIX_OFFSET0_1,
12236 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
12237 osd_reg_write(VPP_OSD1_MATRIX_OFFSET2,
12238 m[20] & 0xfff);
12239 osd_reg_set_bits(VPP_OSD1_MATRIX_EN_CTRL, on, 0, 1);
Googler9726be62022-12-14 05:53:31 +000012240}
Googler9398cc32022-12-02 17:21:52 +080012241
12242static void set_vpp_osd2_rgb2yuv(bool on)
12243{
12244 int *m = NULL;
12245
12246 /* RGB -> 709 limit */
12247 m = RGB709_to_YUV709l_coeff;
12248
12249 /* VPP WRAP OSD3 matrix */
12250 osd_reg_write(VPP_OSD2_MATRIX_PRE_OFFSET0_1,
12251 ((m[0] & 0xfff) << 16) | (m[1] & 0xfff));
12252 osd_reg_write(VPP_OSD2_MATRIX_PRE_OFFSET2,
12253 m[2] & 0xfff);
12254 osd_reg_write(VPP_OSD2_MATRIX_COEF00_01,
12255 ((m[3] & 0x1fff) << 16) | (m[4] & 0x1fff));
12256 osd_reg_write(VPP_OSD2_MATRIX_COEF02_10,
12257 ((m[5] & 0x1fff) << 16) | (m[6] & 0x1fff));
12258 osd_reg_write(VPP_OSD2_MATRIX_COEF11_12,
12259 ((m[7] & 0x1fff) << 16) | (m[8] & 0x1fff));
12260 osd_reg_write(VPP_OSD2_MATRIX_COEF20_21,
12261 ((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff));
12262 osd_reg_write(VPP_OSD2_MATRIX_COEF22,
12263 m[11] & 0x1fff);
12264 osd_reg_write(VPP_OSD2_MATRIX_OFFSET0_1,
12265 ((m[18] & 0xfff) << 16) | (m[19] & 0xfff));
12266 osd_reg_write(VPP_OSD2_MATRIX_OFFSET2,
12267 m[20] & 0xfff);
12268 osd_reg_set_bits(VPP_OSD2_MATRIX_EN_CTRL, on, 0, 1);
12269}
12270
12271static void fix_vpu_clk2_default_regs(void)
12272{
12273 /* t7 eco default setting */
12274 if (osd_hw.osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_T7) {
12275 /* default: osd byp osd_blend */
12276 osd_reg_set_bits(VPP_OSD1_SCALE_CTRL, 0x2, 0, 3);
12277 osd_reg_set_bits(VPP_OSD2_SCALE_CTRL, 0x3, 0, 3);
12278 osd_reg_set_bits(VPP_OSD3_SCALE_CTRL, 0x3, 0, 3);
12279 osd_reg_set_bits(VPP_OSD4_SCALE_CTRL, 0x3, 0, 3);
12280
12281 /* default: osd byp dolby */
12282 osd_reg_set_bits(VPP_VD1_DSC_CTRL, 0x1, 4, 1);
12283 osd_reg_set_bits(VPP_VD2_DSC_CTRL, 0x1, 4, 1);
12284 osd_reg_set_bits(VPP_VD3_DSC_CTRL, 0x1, 4, 1);
12285 osd_reg_set_bits(MALI_AFBCD_TOP_CTRL, 0x1, 14, 1);
12286 osd_reg_set_bits(MALI_AFBCD_TOP_CTRL, 0x1, 19, 1);
12287 osd_reg_set_bits(MALI_AFBCD1_TOP_CTRL, 0x1, 19, 1);
12288 osd_reg_set_bits(MALI_AFBCD1_TOP_CTRL, 0x1, 19, 1);
12289
12290 /* default: osd 12bit path */
12291 osd_reg_set_bits(VPP_VD1_DSC_CTRL, 0x0, 5, 1);
12292 osd_reg_set_bits(VPP_VD2_DSC_CTRL, 0x0, 5, 1);
12293 osd_reg_set_bits(VPP_VD3_DSC_CTRL, 0x0, 5, 1);
12294 osd_reg_set_bits(MALI_AFBCD_TOP_CTRL, 0x0, 15, 1);
12295 osd_reg_set_bits(MALI_AFBCD_TOP_CTRL, 0x0, 20, 1);
12296 osd_reg_set_bits(MALI_AFBCD1_TOP_CTRL, 0x0, 20, 1);
12297 osd_reg_set_bits(MALI_AFBCD1_TOP_CTRL, 0x0, 20, 1);
12298 }
12299}
12300
12301static void independ_path_default_regs(void)
12302{
12303 /* default: osd1_bld_din_sel -- do not osd_data_byp osd_blend */
12304 osd_reg_set_bits(VIU_OSD1_PATH_CTRL, 0x0, 4, 1);
12305 osd_reg_set_bits(VIU_OSD2_PATH_CTRL, 0x0, 4, 1);
12306 osd_reg_set_bits(VIU_OSD3_PATH_CTRL, 0x0, 4, 1);
12307
12308 /* default: osd1_sc_path_sel -- before osd_blend or after hdr */
12309 osd_reg_set_bits(VIU_OSD1_PATH_CTRL, 0x0, 0, 1);
12310 osd_reg_set_bits(VIU_OSD2_PATH_CTRL, 0x1, 0, 1);
12311 osd_reg_set_bits(VIU_OSD3_PATH_CTRL, 0x1, 0, 1);
12312
12313 /* default: osd byp dolby */
12314 osd_reg_set_bits(VIU_VD1_PATH_CTRL, 0x1, 16, 1);
12315 osd_reg_set_bits(VIU_VD2_PATH_CTRL, 0x1, 16, 1);
12316 osd_reg_set_bits(VIU_OSD1_PATH_CTRL, 0x1, 16, 1);
12317 osd_reg_set_bits(VIU_OSD2_PATH_CTRL, 0x1, 16, 1);
12318 osd_reg_set_bits(VIU_OSD3_PATH_CTRL, 0x1, 16, 1);
12319
12320 /* default: osd 12bit path */
12321 osd_reg_set_bits(VIU_VD1_PATH_CTRL, 0x0, 17, 1);
12322 osd_reg_set_bits(VIU_VD2_PATH_CTRL, 0x0, 17, 1);
12323 osd_reg_set_bits(VIU_OSD1_PATH_CTRL, 0x0, 17, 1);
12324 osd_reg_set_bits(VIU_OSD2_PATH_CTRL, 0x0, 17, 1);
12325 osd_reg_set_bits(VIU_OSD3_PATH_CTRL, 0x0, 17, 1);
12326}
12327
12328static void multi_afbc_default_path_setting(void)
12329{
12330 if (osd_dev_hw.path_ctrl_independ)
12331 independ_path_default_regs();
12332 else
12333 fix_vpu_clk2_default_regs();
12334}
12335
12336static void osd_set_vpp_path_default(u32 osd_index, u32 vpp_index)
12337{
12338 if (osd_dev_hw.has_multi_vpp) {
12339 /* osd_index is vpp mux input */
12340 /* default setting osd2 route to vpp0 vsync */
12341 if (osd_index == VPP_OSD3)
12342 osd_reg_set_bits(PATH_START_SEL,
12343 vpp_index, 24, 2);
12344 /* default setting osd3 route to vpp0 vsync */
12345 if (osd_index == VPP_OSD4)
12346 osd_reg_set_bits(PATH_START_SEL,
12347 vpp_index, 28, 2);
12348 }
12349}
12350
12351static void set_rdma_func_handler(void)
12352{
12353 osd_hw.osd_rdma_func[0].osd_rdma_rd =
12354 VSYNCOSD_RD_MPEG_REG;
12355 osd_hw.osd_rdma_func[0].osd_rdma_wr =
12356 VSYNCOSD_WR_MPEG_REG;
12357 osd_hw.osd_rdma_func[0].osd_rdma_wr_bits =
12358 VSYNCOSD_WR_MPEG_REG_BITS;
12359 osd_hw.osd_rdma_func[0].osd_rdma_set_mask =
12360 VSYNCOSD_SET_MPEG_REG_MASK;
12361 osd_hw.osd_rdma_func[0].osd_rdma_clr_mask =
12362 VSYNCOSD_CLR_MPEG_REG_MASK;
12363 osd_hw.osd_rdma_func[0].osd_rdma_wr_irq =
12364 VSYNCOSD_IRQ_WR_MPEG_REG;
12365
12366 osd_hw.osd_rdma_func[1].osd_rdma_rd =
12367 VSYNCOSD_RD_MPEG_REG_VPP1;
12368 osd_hw.osd_rdma_func[1].osd_rdma_wr =
12369 VSYNCOSD_WR_MPEG_REG_VPP1;
12370 osd_hw.osd_rdma_func[1].osd_rdma_wr_bits =
12371 VSYNCOSD_WR_MPEG_REG_BITS_VPP1;
12372 osd_hw.osd_rdma_func[1].osd_rdma_set_mask =
12373 VSYNCOSD_SET_MPEG_REG_MASK_VPP1;
12374 osd_hw.osd_rdma_func[1].osd_rdma_clr_mask =
12375 VSYNCOSD_CLR_MPEG_REG_MASK_VPP1;
12376 osd_hw.osd_rdma_func[1].osd_rdma_wr_irq =
12377 VSYNCOSD_IRQ_WR_MPEG_REG_VPP1;
12378
12379 osd_hw.osd_rdma_func[2].osd_rdma_rd =
12380 VSYNCOSD_RD_MPEG_REG_VPP2;
12381 osd_hw.osd_rdma_func[2].osd_rdma_wr =
12382 VSYNCOSD_WR_MPEG_REG_VPP2;
12383 osd_hw.osd_rdma_func[2].osd_rdma_wr_bits =
12384 VSYNCOSD_WR_MPEG_REG_BITS_VPP2;
12385 osd_hw.osd_rdma_func[2].osd_rdma_set_mask =
12386 VSYNCOSD_SET_MPEG_REG_MASK_VPP2;
12387 osd_hw.osd_rdma_func[2].osd_rdma_clr_mask =
12388 VSYNCOSD_CLR_MPEG_REG_MASK_VPP2;
12389 osd_hw.osd_rdma_func[2].osd_rdma_wr_irq =
12390 VSYNCOSD_IRQ_WR_MPEG_REG_VPP2;
12391}
Googler9726be62022-12-14 05:53:31 +000012392
Googler4f18c0c2022-09-20 17:23:36 +080012393void osd_init_hw(u32 logo_loaded, u32 osd_probe,
Googler9398cc32022-12-02 17:21:52 +080012394 struct osd_device_data_s *osd_meson)
Googler4f18c0c2022-09-20 17:23:36 +080012395{
12396 u32 idx, data32;
12397 int err_num = 0;
Googler9398cc32022-12-02 17:21:52 +080012398#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
12399 void *osd_secure_op[VPP_TOP_MAX] = {VSYNCOSD_WR_MPEG_REG_BITS,
12400 VSYNCOSD_WR_MPEG_REG_BITS_VPP1,
12401 VSYNCOSD_WR_MPEG_REG_BITS_VPP2};
12402#endif
Googler4f18c0c2022-09-20 17:23:36 +080012403#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
12404 int i = 0;
12405
12406 for (i = 0 ; i < HW_OSD_COUNT; i++)
12407 displayed_bufs[i] = NULL;
12408#endif
12409
12410 osd_hw.fb_drvier_probe = osd_probe;
Googler9398cc32022-12-02 17:21:52 +080012411 osd_hw.vpp_num = 1;
Googler4f18c0c2022-09-20 17:23:36 +080012412
12413 memcpy(&osd_hw.osd_meson_dev, osd_meson,
Googler9398cc32022-12-02 17:21:52 +080012414 sizeof(struct osd_device_data_s));
12415 if (osd_hw.osd_meson_dev.has_vpp1)
12416 osd_hw.vpp_num++;
12417 if (osd_hw.osd_meson_dev.has_vpp2)
12418 osd_hw.vpp_num++;
Googler4f18c0c2022-09-20 17:23:36 +080012419 osd_vpu_power_on();
Googler9398cc32022-12-02 17:21:52 +080012420 if (osd_meson->osd_count == 3 &&
12421 osd_meson->has_viu2) {
Googler4f18c0c2022-09-20 17:23:36 +080012422 /* VIU1 2 OSD + 1 VIU2 1 OSD*/
12423 memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_tl1[0],
Googler9398cc32022-12-02 17:21:52 +080012424 sizeof(struct hw_osd_reg_s) *
12425 osd_hw.osd_meson_dev.osd_count);
12426 } else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_T7) {
12427 /* 4 or 3 OSD, multi_afbc_core */
12428 memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_t7[0],
12429 sizeof(struct hw_osd_reg_s) *
12430 osd_hw.osd_meson_dev.osd_count);
12431 } else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_T3 ||
12432 osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_T5W) {
12433 /* 4 or 3 OSD, multi_afbc_core */
12434 memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_t3[0],
12435 sizeof(struct hw_osd_reg_s) *
12436 osd_hw.osd_meson_dev.osd_count);
Googler4f18c0c2022-09-20 17:23:36 +080012437 } else {
12438 /* VIU1 3 OSD + 1 VIU2 1 OSD or VIU1 2 OSD*/
12439 memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_g12a[0],
Googler9398cc32022-12-02 17:21:52 +080012440 sizeof(struct hw_osd_reg_s) *
12441 osd_hw.osd_meson_dev.osd_count);
Googler4f18c0c2022-09-20 17:23:36 +080012442 }
Googler9398cc32022-12-02 17:21:52 +080012443 if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXTVBB) {
12444#ifndef CONFIG_AMLOGIC_REMOVE_OLD
Googler4f18c0c2022-09-20 17:23:36 +080012445 backup_regs_init(HW_RESET_AFBCD_REGS);
Googler9398cc32022-12-02 17:21:52 +080012446#endif
12447 } else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXM) {
12448#ifndef CONFIG_AMLOGIC_REMOVE_OLD
Googler4f18c0c2022-09-20 17:23:36 +080012449 backup_regs_init(HW_RESET_OSD1_REGS);
Googler9398cc32022-12-02 17:21:52 +080012450#endif
12451 } else if ((osd_meson->cpu_id >= __MESON_CPU_MAJOR_ID_GXL) &&
12452 osd_meson->cpu_id <= __MESON_CPU_MAJOR_ID_TXL) {
12453#ifndef CONFIG_AMLOGIC_REMOVE_OLD
Googler4f18c0c2022-09-20 17:23:36 +080012454 backup_regs_init(HW_RESET_OSD1_REGS);
Googler9398cc32022-12-02 17:21:52 +080012455#endif
12456 } else if (osd_meson->cpu_id >= __MESON_CPU_MAJOR_ID_G12A) {
12457 if (osd_dev_hw.multi_afbc_core)
12458 backup_regs_init(HW_RESET_MALI_AFBCD_REGS |
12459 HW_RESET_MALI_AFBCD1_REGS |
12460 HW_RESET_MALI_AFBCD2_REGS);
12461 else
12462 backup_regs_init(HW_RESET_MALI_AFBCD_REGS);
12463 } else {
Googler4f18c0c2022-09-20 17:23:36 +080012464 backup_regs_init(HW_RESET_NONE);
Googler9398cc32022-12-02 17:21:52 +080012465 }
Googler4f18c0c2022-09-20 17:23:36 +080012466
12467 recovery_regs_init();
Googler9398cc32022-12-02 17:21:52 +080012468 /* set osd vpp rdma func */
12469 set_rdma_func_handler();
Googler4f18c0c2022-09-20 17:23:36 +080012470 for (idx = 0; idx < HW_REG_INDEX_MAX; idx++)
12471 osd_hw.reg[idx].update_func =
12472 hw_func_array[idx];
12473
12474#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
12475 osd_hdr_on = false;
12476#endif
12477 osd_hw.hw_reset_flag = HW_RESET_NONE;
12478 osd_hw.hwc_enable[VIU1] = 0;
12479 osd_hw.hwc_enable[VIU2] = 0;
12480 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
12481 osd_hw.hw_cursor_en = 1;
12482 if (osd_hw.osd_meson_dev.has_rdma)
12483 osd_hw.hw_rdma_en = 1;
12484 } else if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
12485 osd_hw.hw_cursor_en = 0;
12486 if (osd_hw.osd_meson_dev.has_rdma)
12487 osd_hw.hw_rdma_en = 1;
12488 /* g12a and g12b need delay */
12489 supsend_delay = 50;
12490 }
12491 /* here we will init default value ,these value only set once . */
12492 if (!logo_loaded) {
Googler9398cc32022-12-02 17:21:52 +080012493 if (osd_dev_hw.multi_afbc_core)
12494 multi_afbc_default_path_setting();
12495
Googler4f18c0c2022-09-20 17:23:36 +080012496 /* init vpu fifo control register */
12497 data32 = osd_reg_read(VPP_OFIFO_SIZE);
12498 if (osd_hw.osd_meson_dev.osd_ver >= OSD_HIGH_ONE) {
12499 data32 &= ~((0xfff << 20) | 0x3fff);
12500 data32 |= (osd_hw.osd_meson_dev.vpp_fifo_len) << 20;
12501 data32 |= osd_hw.osd_meson_dev.vpp_fifo_len + 1;
Googler9398cc32022-12-02 17:21:52 +080012502 } else {
Googler4f18c0c2022-09-20 17:23:36 +080012503 data32 |= osd_hw.osd_meson_dev.vpp_fifo_len;
Googler9398cc32022-12-02 17:21:52 +080012504 }
Googler4f18c0c2022-09-20 17:23:36 +080012505 osd_reg_write(VPP_OFIFO_SIZE, data32);
12506 data32 = 0x08080808;
12507 osd_reg_write(VPP_HOLD_LINES, data32);
12508
12509 /* init osd fifo control register
12510 * set DDR request priority to be urgent
12511 */
12512 data32 = 1;
Googler9726be62022-12-14 05:53:31 +000012513 /* hold_fifo_lines */
12514 if (osd_hw.osd_meson_dev.osd_ver >= OSD_HIGH_ONE)
12515 data32 |= VIU1_DEFAULT_HOLD_LINE << 5;
12516 else
12517 data32 |= MIN_HOLD_LINE << 5;
Googler4f18c0c2022-09-20 17:23:36 +080012518 /* burst_len_sel: 3=64, g12a = 5 */
12519 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
12520 data32 |= 1 << 10;
12521 data32 |= 1 << 31;
Googler9398cc32022-12-02 17:21:52 +080012522 } else {
Googler4f18c0c2022-09-20 17:23:36 +080012523 data32 |= 3 << 10;
Googler9398cc32022-12-02 17:21:52 +080012524 }
Googler4f18c0c2022-09-20 17:23:36 +080012525 /*
12526 * bit 23:22, fifo_ctrl
12527 * 00 : for 1 word in 1 burst
12528 * 01 : for 2 words in 1 burst
12529 * 10 : for 4 words in 1 burst
12530 * 11 : reserved
12531 */
12532 data32 |= 2 << 22;
12533 /* bit 28:24, fifo_lim */
12534 data32 |= 2 << 24;
12535
12536 /* data32_ = data32; */
12537 /* fifo_depth_val: 32 or 64 *8 = 256 or 512 */
12538 data32 |= (osd_hw.osd_meson_dev.osd_fifo_len
12539 & 0xfffffff) << 12;
12540 for (idx = 0; idx < osd_hw.osd_meson_dev.viu1_osd_count; idx++)
Googler9398cc32022-12-02 17:21:52 +080012541 osd_reg_write(hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
12542 data32);
Googler4f18c0c2022-09-20 17:23:36 +080012543 /* osd_reg_write(VIU_OSD2_FIFO_CTRL_STAT, data32_); */
12544 osd_reg_set_mask(VPP_MISC, VPP_POSTBLEND_EN);
12545 osd_reg_clr_mask(VPP_MISC, VPP_PREBLEND_EN);
12546 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
12547 osd_vpp_misc =
12548 osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS;
12549 osd_vpp_misc &=
12550 ~(VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND);
12551
12552 notify_to_amvideo();
12553 osd_reg_clr_mask(VPP_MISC,
Googler9398cc32022-12-02 17:21:52 +080012554 VPP_OSD1_POSTBLEND |
12555 VPP_OSD2_POSTBLEND);
Googler4f18c0c2022-09-20 17:23:36 +080012556 }
12557 /* just disable osd to avoid booting hang up */
12558 data32 = 0x1 << 0;
12559 data32 |= OSD_GLOBAL_ALPHA_DEF << 12;
12560 for (idx = 0; idx < osd_hw.osd_meson_dev.viu1_osd_count; idx++)
Googler9398cc32022-12-02 17:21:52 +080012561 osd_reg_write(hw_osd_reg_array[idx].osd_ctrl_stat,
12562 data32);
Googler9726be62022-12-14 05:53:31 +000012563 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE)
12564 osd_setting_default_hwc();
Googler4f18c0c2022-09-20 17:23:36 +080012565 }
12566 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
12567 osd_vpp_misc =
12568 osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS;
12569 if (osd_hw.hw_cursor_en) {
12570 osd_vpp_misc |= (VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2);
12571 notify_to_amvideo();
12572 osd_reg_set_mask(VPP_MISC,
Googler9398cc32022-12-02 17:21:52 +080012573 VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2);
Googler4f18c0c2022-09-20 17:23:36 +080012574 osd_hw.order[OSD1] = OSD_ORDER_10;
12575 } else {
12576 osd_vpp_misc &= ~(VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2);
12577 notify_to_amvideo();
12578 osd_reg_clr_mask(VPP_MISC,
Googler9398cc32022-12-02 17:21:52 +080012579 VPP_POST_FG_OSD2 |
12580 VPP_PRE_FG_OSD2);
Googler4f18c0c2022-09-20 17:23:36 +080012581 osd_hw.order[OSD1] = OSD_ORDER_01;
12582 }
12583 } else if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
12584 osd_hw.order[OSD1] = LAYER_1;
12585 osd_hw.order[OSD2] = LAYER_2;
12586 osd_hw.order[OSD3] = LAYER_3;
12587 for (idx = 0; idx < VIU_COUNT; idx++) {
12588 osd_hw.disp_info[idx].background_w = 1920;
12589 osd_hw.disp_info[idx].background_h = 1080;
12590 osd_hw.disp_info[idx].fullscreen_w = 1920;
12591 osd_hw.disp_info[idx].fullscreen_h = 1080;
12592 osd_hw.disp_info[idx].position_x = 0;
12593 osd_hw.disp_info[idx].position_y = 0;
12594 osd_hw.disp_info[idx].position_w = 1920;
12595 osd_hw.disp_info[idx].background_h = 1080;
12596 osd_hw.vinfo_width[idx] = 1920;
12597 osd_hw.vinfo_height[idx] = 1080;
12598 }
12599 if ((osd_hw.osd_meson_dev.cpu_id ==
12600 __MESON_CPU_MAJOR_ID_G12A) ||
12601 ((osd_hw.osd_meson_dev.cpu_id ==
12602 __MESON_CPU_MAJOR_ID_G12B) &&
12603 is_meson_rev_a()))
12604 osd_hw.workaround_line = 1;
12605 for (idx = 0; idx < osd_hw.osd_meson_dev.osd_count; idx++) {
12606 osd_hw.premult_en[idx] = 0;
12607 osd_hw.osd_afbcd[idx].format = COLOR_INDEX_32_ABGR;
12608 osd_hw.osd_afbcd[idx].inter_format =
12609 MALI_AFBC_32X8_PIXEL << 1 |
12610 MALI_AFBC_SPLIT_ON;
12611 osd_hw.osd_afbcd[idx].afbc_start = 0;
12612
12613 osd_hw.osd_afbcd[idx].out_addr_id = idx + 1;
12614 if (osd_hw.osd_meson_dev.cpu_id ==
12615 __MESON_CPU_MAJOR_ID_G12A) {
12616 osd_hw.afbc_force_reset = 1;
12617 osd_hw.afbc_regs_backup = 1;
Googler4f18c0c2022-09-20 17:23:36 +080012618 }
12619
12620 if (idx < osd_hw.osd_meson_dev.viu1_osd_count) {
12621 /* TODO: temp set at here,
12622 * need move it to uboot
12623 */
Googler9398cc32022-12-02 17:21:52 +080012624 osd_reg_set_bits
12625 (hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
12626 1, 31, 1);
12627 osd_reg_set_bits
12628 (hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
12629 1, 10, 2);
12630 osd_reg_set_bits
12631 (hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
12632 VIU1_DEFAULT_HOLD_LINE, 5, 5);
Googler4f18c0c2022-09-20 17:23:36 +080012633 if (osd_hw.osd_meson_dev.cpu_id ==
12634 __MESON_CPU_MAJOR_ID_G12B)
12635 osd_reg_set_bits
12636 (hw_osd_reg_array[idx].osd_ctrl_stat,
12637 1, 0, 1);
Googler9398cc32022-12-02 17:21:52 +080012638 osd_reg_set_bits
12639 (hw_osd_reg_array[idx].osd_ctrl_stat,
12640 0, 31, 1);
Googler4f18c0c2022-09-20 17:23:36 +080012641 osd_hw.powered[idx] = 1;
Googler9398cc32022-12-02 17:21:52 +080012642 } else {
Googler4f18c0c2022-09-20 17:23:36 +080012643 osd_hw.powered[idx] = 0;
Googler9398cc32022-12-02 17:21:52 +080012644 }
Googler4f18c0c2022-09-20 17:23:36 +080012645 }
Googler4f18c0c2022-09-20 17:23:36 +080012646 osd_set_basic_urgent(true);
12647 osd_set_two_ports(true);
Googler9398cc32022-12-02 17:21:52 +080012648 osd_set_vpp_path_default(VPP_OSD3,
12649 get_output_device_id(OSD3));
12650 osd_set_vpp_path_default(VPP_OSD4,
12651 get_output_device_id(OSD4));
Googler4f18c0c2022-09-20 17:23:36 +080012652 }
12653 /* disable deband as default */
12654 if (osd_hw.osd_meson_dev.has_deband)
12655 osd_reg_write(OSD_DB_FLT_CTRL, 0);
12656 for (idx = 0; idx < osd_hw.osd_meson_dev.osd_count; idx++) {
12657 osd_hw.updated[idx] = 0;
12658 osd_hw.urgent[idx] = 1;
12659 osd_hw.enable[idx] = DISABLE;
12660 osd_hw.fb_gem[idx].xres = 0;
12661 osd_hw.fb_gem[idx].yres = 0;
12662 osd_hw.gbl_alpha[idx] = OSD_GLOBAL_ALPHA_DEF;
12663 osd_hw.color_info[idx] = NULL;
12664 osd_hw.color_backup[idx] = NULL;
12665 osd_hw.color_key[idx] = 0xffffffff;
12666 osd_hw.color_key_enable[idx] = 0;
12667 osd_hw.mode_3d[idx].enable = 0;
12668 osd_hw.block_mode[idx] = 0;
12669 osd_hw.osd_reverse[idx] = REVERSE_FALSE;
12670 osd_hw.free_scale_enable[idx] = 0;
12671 osd_hw.free_scale_enable_backup[idx] = 0;
12672 osd_hw.scale[idx].h_enable = 0;
12673 osd_hw.scale[idx].v_enable = 0;
12674 osd_hw.free_scale[idx].h_enable = 0;
12675 osd_hw.free_scale[idx].h_enable = 0;
12676 osd_hw.free_scale_backup[idx].h_enable = 0;
12677 osd_hw.free_scale_backup[idx].v_enable = 0;
12678 osd_hw.free_src_data[idx].x_start = 0;
12679 osd_hw.free_src_data[idx].x_end = 0;
12680 osd_hw.free_src_data[idx].y_start = 0;
12681 osd_hw.free_src_data[idx].y_end = 0;
12682 osd_hw.free_src_data_backup[idx].x_start = 0;
12683 osd_hw.free_src_data_backup[idx].x_end = 0;
12684 osd_hw.free_src_data_backup[idx].y_start = 0;
12685 osd_hw.free_src_data_backup[idx].y_end = 0;
12686 osd_hw.free_scale_mode[idx] = 0;
12687 osd_hw.buffer_alloc[idx] = 0;
12688 osd_hw.osd_afbcd[idx].enable = 0;
Googler9398cc32022-12-02 17:21:52 +080012689 osd_hw.osd_afbcd[idx].phy_addr = 0;
Googler4f18c0c2022-09-20 17:23:36 +080012690 osd_hw.use_h_filter_mode[idx] = -1;
12691 osd_hw.use_v_filter_mode[idx] = -1;
12692 osd_hw.premult_en[idx] = 0;
Googler9398cc32022-12-02 17:21:52 +080012693 osd_hw.afbc_err_cnt[idx] = 0;
12694 osd_hw.blend_bypass[idx] = 0;
12695 osd_hw.osd_deband_enable[idx] = 1;
12696 if (osd_dev_hw.remove_afbc == idx + 1)
12697 osd_hw.afbc_support[idx] = false;
12698 else
12699 osd_hw.afbc_support[idx] = true;
12700 if (osd_dev_hw.remove_pps == idx + 1)
12701 osd_hw.pps_support[idx] = false;
12702 else
12703 osd_hw.pps_support[idx] = true;
Googler4f18c0c2022-09-20 17:23:36 +080012704 /*
12705 * osd_hw.rotation_pandata[idx].x_start = 0;
12706 * osd_hw.rotation_pandata[idx].y_start = 0;
12707 */
12708 osd_set_dummy_data(idx, 0xff);
Googler9398cc32022-12-02 17:21:52 +080012709 osd_set_deband(idx, osd_hw.osd_deband_enable[idx]);
Googler4f18c0c2022-09-20 17:23:36 +080012710 }
12711 /* hwc_enable == 0 handler */
12712#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
12713 osd_hw.osd_fence[VIU1][DISABLE].sync_fence_handler =
12714 sync_render_single_fence;
12715 osd_hw.osd_fence[VIU1][DISABLE].toggle_buffer_handler =
12716 osd_toggle_buffer_single;
12717 /* hwc_enable == 1 handler */
12718 osd_hw.osd_fence[VIU1][ENABLE].sync_fence_handler =
12719 sync_render_layers_fence;
12720 osd_hw.osd_fence[VIU1][ENABLE].toggle_buffer_handler =
12721 osd_toggle_buffer_layers;
Googler9398cc32022-12-02 17:21:52 +080012722 if (osd_hw.osd_meson_dev.has_viu2 || osd_hw.osd_meson_dev.has_vpp1) {
Googler4f18c0c2022-09-20 17:23:36 +080012723 osd_hw.osd_fence[VIU2][DISABLE].sync_fence_handler =
12724 sync_render_single_fence;
12725 osd_hw.osd_fence[VIU2][DISABLE].toggle_buffer_handler =
12726 osd_toggle_buffer_single_viu2;
12727 /* hwc_enable == 1 handler */
12728 osd_hw.osd_fence[VIU2][ENABLE].sync_fence_handler =
12729 sync_render_layers_fence;
12730 osd_hw.osd_fence[VIU2][ENABLE].toggle_buffer_handler =
12731 osd_toggle_buffer_layers_viu2;
12732 }
12733#endif
12734 osd_hw.fb_gem[OSD1].canvas_idx = OSD1_CANVAS_INDEX;
12735 osd_hw.fb_gem[OSD2].canvas_idx = OSD2_CANVAS_INDEX;
12736 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
12737 osd_hw.fb_gem[OSD3].canvas_idx = OSD3_CANVAS_INDEX;
12738 if (osd_hw.osd_meson_dev.osd_count == 4)
Googler9398cc32022-12-02 17:21:52 +080012739 osd_hw.fb_gem[OSD4].canvas_idx = OSD4_CANVAS_INDEX;
Googler4f18c0c2022-09-20 17:23:36 +080012740 }
12741 osd_extra_canvas_alloc();
12742 osd_hw.antiflicker_mode = 0;
Googler4f18c0c2022-09-20 17:23:36 +080012743 osd_hw.out_fence_fd[VIU1] = -1;
12744 osd_hw.out_fence_fd[VIU2] = -1;
Googler9726be62022-12-14 05:53:31 +000012745 osd_hw.osd_preblend_en = 0;
12746 osd_hw.fix_target_width = 1920;
12747 osd_hw.fix_target_height = 1080;
Googler4f18c0c2022-09-20 17:23:36 +080012748 if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) {
Googler9398cc32022-12-02 17:21:52 +080012749 data32 = osd_reg_read
12750 (hw_osd_reg_array[OSD1].osd_fifo_ctrl_stat);
Googler4f18c0c2022-09-20 17:23:36 +080012751 /* bit[9:5]: HOLD_FIFO_LINES */
12752 data32 &= ~(0x1f << 5);
12753 data32 |= 0x18 << 5;
Googler9398cc32022-12-02 17:21:52 +080012754 osd_reg_write(hw_osd_reg_array[OSD1].osd_fifo_ctrl_stat,
12755 data32);
Googler4f18c0c2022-09-20 17:23:36 +080012756 }
Googler9398cc32022-12-02 17:21:52 +080012757 if (osd_hw.osd_meson_dev.osd_rgb2yuv == 1) {
12758 set_vpp_osd1_rgb2yuv(1);
12759 set_vpp_osd2_rgb2yuv(1);
12760 }
Googler4f18c0c2022-09-20 17:23:36 +080012761 if (osd_hw.fb_drvier_probe) {
12762#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
12763 INIT_LIST_HEAD(&post_fence_list[VIU1]);
12764 mutex_init(&post_fence_list_lock[VIU1]);
12765 INIT_LIST_HEAD(&post_fence_list[VIU2]);
12766 mutex_init(&post_fence_list_lock[VIU2]);
12767#endif
12768#ifdef FIQ_VSYNC
12769 osd_hw.fiq_handle_item.handle = vsync_isr;
12770 osd_hw.fiq_handle_item.key = (u32)vsync_isr;
12771 osd_hw.fiq_handle_item.name = "osd_vsync";
12772 if (register_fiq_bridge_handle(&osd_hw.fiq_handle_item))
12773 osd_log_err("can't request irq for vsync,err_num=%d\n",
Googler9398cc32022-12-02 17:21:52 +080012774 -err_num);
Googler4f18c0c2022-09-20 17:23:36 +080012775#else
12776 err_num = request_irq(int_viu_vsync, &vsync_isr,
Googler9398cc32022-12-02 17:21:52 +080012777 IRQF_SHARED, "osd-vsync", osd_setup_hw);
Googler4f18c0c2022-09-20 17:23:36 +080012778 if (err_num)
12779 osd_log_err("can't request irq for vsync,err_num=%d\n",
Googler9398cc32022-12-02 17:21:52 +080012780 -err_num);
12781 if (osd_hw.osd_meson_dev.has_viu2 || osd_hw.osd_meson_dev.has_vpp1) {
Googler4f18c0c2022-09-20 17:23:36 +080012782 err_num = request_irq(int_viu2_vsync, &vsync_viu2_isr,
Googler9398cc32022-12-02 17:21:52 +080012783 IRQF_SHARED,
12784 "osd-vsync-viu2", osd_setup_hw);
Googler4f18c0c2022-09-20 17:23:36 +080012785 if (err_num)
12786 osd_log_err("can't request irq for viu2 vsync,err_num=%d\n",
Googler9398cc32022-12-02 17:21:52 +080012787 -err_num);
12788 }
12789 if (osd_hw.osd_meson_dev.has_vpp2) {
12790 err_num = request_irq(int_viu3_vsync, &vsync_viu3_isr,
12791 IRQF_SHARED,
12792 "osd-vsync-viu3", osd_setup_hw);
12793 if (err_num)
12794 osd_log_err("can't request irq for viu3 vsync,err_num=%d\n",
12795 -err_num);
Googler4f18c0c2022-09-20 17:23:36 +080012796 }
12797#endif
12798#ifdef FIQ_VSYNC
12799 request_fiq(INT_VIU_VSYNC, &osd_fiq_isr);
12800 request_fiq(INT_VIU_VSYNC, &osd_viu2_fiq_isr);
12801#endif
12802 }
Googler9398cc32022-12-02 17:21:52 +080012803 if (osd_hw.hw_rdma_en) {
12804 osd_rdma_enable(VPU_VPP0, 2);
12805 if (osd_hw.osd_meson_dev.has_vpp1 &&
12806 osd_hw.display_dev_cnt == 2)
12807 osd_rdma_enable(VPU_VPP1, 2);
12808 if (osd_hw.osd_meson_dev.has_vpp2 &&
12809 osd_hw.display_dev_cnt == 3)
12810 osd_rdma_enable(VPU_VPP2, 2);
12811 } else {
12812 osd_hw.afbc_force_reset = 0;
12813 }
Googler9726be62022-12-14 05:53:31 +000012814#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
12815 affinity_set_init();
12816#endif
12817#ifdef CONFIG_AMLOGIC_MEDIA_SECURITY
12818 secure_register(OSD_MODULE, 0,
Googler9398cc32022-12-02 17:21:52 +080012819 osd_secure_op,
12820 osd_secure_cb);
Googler9726be62022-12-14 05:53:31 +000012821#endif
Googler9398cc32022-12-02 17:21:52 +080012822
Googler9726be62022-12-14 05:53:31 +000012823 osd_log_out = 1;
12824}
12825
12826void set_viu2_format(u32 format)
12827{
Googler9398cc32022-12-02 17:21:52 +080012828 if (is_yuv_format(format))
Googler9726be62022-12-14 05:53:31 +000012829 set_viu2_rgb2yuv(1);
Googler9398cc32022-12-02 17:21:52 +080012830 else
Googler9726be62022-12-14 05:53:31 +000012831 set_viu2_rgb2yuv(0);
Googler4f18c0c2022-09-20 17:23:36 +080012832}
12833
12834void osd_init_viu2(void)
12835{
12836 u32 idx, data32;
Googler9726be62022-12-14 05:53:31 +000012837#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
Googler9398cc32022-12-02 17:21:52 +080012838 struct vinfo_s *vinfo;
Googler9726be62022-12-14 05:53:31 +000012839 vinfo = get_current_vinfo2();
Googler9398cc32022-12-02 17:21:52 +080012840 if (vinfo && vinfo->name && (strcmp(vinfo->name, "invalid") &&
12841 strcmp(vinfo->name, "null")))
12842 set_viu2_format(vinfo->viu_color_fmt);
Googler9726be62022-12-14 05:53:31 +000012843#endif
Googler4f18c0c2022-09-20 17:23:36 +080012844
Googler0109c452022-10-13 17:50:39 +080012845 idx = osd_hw.osd_meson_dev.viu2_index;
Googler9726be62022-12-14 05:53:31 +000012846 if (osd_get_logo_index() != LOGO_DEV_VIU2_OSD0) {
12847 set_viu2_rgb2yuv(1);
12848 osd_vpu_power_on_viu2();
12849 /* here we will init default value, these value only set once */
12850 /* init vpu fifo control register */
12851 osd_reg_write(VPP2_OFIFO_SIZE, 0x7ff00800);
12852 /* init osd fifo control register
12853 * set DDR request priority to be urgent
12854 */
12855 data32 = 0x1 << 0;
12856 data32 |= OSD_GLOBAL_ALPHA_DEF << 12;
Googler9398cc32022-12-02 17:21:52 +080012857 osd_reg_write(hw_osd_reg_array[idx].osd_ctrl_stat, data32);
12858
12859 osd_reg_set_bits(hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
12860 1, 31, 1);
12861 osd_reg_set_bits(hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
12862 1, 10, 2);
Googler9726be62022-12-14 05:53:31 +000012863
12864 data32 = 0;
Googler9398cc32022-12-02 17:21:52 +080012865 data32 = osd_reg_read(hw_osd_reg_array[idx].osd_ctrl_stat);
Googler9726be62022-12-14 05:53:31 +000012866 data32 |= 0x80000000;
Googler9398cc32022-12-02 17:21:52 +080012867 osd_reg_write(hw_osd_reg_array[idx].osd_ctrl_stat, data32);
Googler9726be62022-12-14 05:53:31 +000012868
12869 data32 = 1;
12870 data32 |= VIU2_DEFAULT_HOLD_LINE << 5; /* hold_fifo_lines */
12871 /* burst_len_sel: 3=64, g12a = 5 */
12872 if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
12873 data32 |= 1 << 10;
12874 data32 |= 1 << 31;
Googler9398cc32022-12-02 17:21:52 +080012875 } else {
Googler9726be62022-12-14 05:53:31 +000012876 data32 |= 3 << 10;
Googler9398cc32022-12-02 17:21:52 +080012877 }
Googler9726be62022-12-14 05:53:31 +000012878 /*
12879 * bit 23:22, fifo_ctrl
12880 * 00 : for 1 word in 1 burst
12881 * 01 : for 2 words in 1 burst
12882 * 10 : for 4 words in 1 burst
12883 * 11 : reserved
12884 */
12885 data32 |= 2 << 22;
12886 /* bit 28:24, fifo_lim */
12887 data32 |= 2 << 24;
12888 /* data32_ = data32; */
12889 /* fifo_depth_val: 32 or 64 *8 = 256 or 512 */
Googler9398cc32022-12-02 17:21:52 +080012890 data32 |= (osd_hw.osd_meson_dev.osd_fifo_len & 0xfffffff) << 12;
12891 osd_reg_write(hw_osd_reg_array[idx].osd_fifo_ctrl_stat, data32);
Googler9726be62022-12-14 05:53:31 +000012892 }
12893
Googler4f18c0c2022-09-20 17:23:36 +080012894 /* enable for latch */
12895 osd_hw.osd_use_latch[idx] = 1;
12896 /* init osd reverse */
12897 osd_get_reverse_hw(idx, &data32);
12898 if (data32)
12899 osd_set_reverse_hw(idx, data32, 1);
Googler9726be62022-12-14 05:53:31 +000012900 viu2_osd_reg_table_init();
Googler4f18c0c2022-09-20 17:23:36 +080012901 osd_hw.powered[idx] = 1;
12902}
12903
12904void osd_cursor_hw(u32 index, s16 x, s16 y, s16 xstart, s16 ystart, u32 osd_w,
12905 u32 osd_h)
12906{
12907 struct pandata_s disp_tmp;
12908 int w = 0, h = 0;
12909 int w_diff = 0;
12910
12911 if (index != 1)
12912 return;
12913
12914 osd_log_dbg(MODULE_CURSOR, "cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n",
Googler9398cc32022-12-02 17:21:52 +080012915 x, y, xstart, ystart, osd_w, osd_h);
Googler4f18c0c2022-09-20 17:23:36 +080012916
12917 if (osd_hw.free_scale_mode[OSD1]) {
12918 if (osd_hw.free_scale_enable[OSD1])
12919 memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080012920 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +080012921 else
12922 memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080012923 sizeof(struct pandata_s));
12924 } else {
Googler4f18c0c2022-09-20 17:23:36 +080012925 memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080012926 sizeof(struct pandata_s));
12927 }
Googler4f18c0c2022-09-20 17:23:36 +080012928
12929 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
12930 if (osd_hw.free_scale_enable[OSD1]) {
12931 w = osd_hw.free_src_data[OSD1].x_end -
12932 osd_hw.free_src_data[OSD1].x_start + 1;
12933 h = osd_hw.free_src_data[OSD1].y_end -
12934 osd_hw.free_src_data[OSD1].y_start + 1;
12935 } else {
12936 w = osd_hw.pandata[OSD1].x_end -
12937 osd_hw.pandata[OSD1].x_start + 1;
12938 h = osd_hw.pandata[OSD1].y_end -
12939 osd_hw.pandata[OSD1].y_start + 1;
12940 }
12941 x = w - x;
12942 y = h - y;
12943 }
12944 if (osd_hw.scale[OSD1].h_enable)
12945 osd_hw.scaledata[OSD2].x_end *= 2;
12946 if (osd_hw.scale[OSD1].v_enable)
12947 osd_hw.scaledata[OSD2].y_end *= 2;
Googler9398cc32022-12-02 17:21:52 +080012948 if (osd_hw.scale[OSD2].h_enable &&
12949 osd_hw.scaledata[OSD2].x_start > 0 &&
12950 osd_hw.scaledata[OSD2].x_end > 0) {
Googler4f18c0c2022-09-20 17:23:36 +080012951 x = x * osd_hw.scaledata[OSD2].x_end /
12952 osd_hw.scaledata[OSD2].x_start;
12953 }
Googler9398cc32022-12-02 17:21:52 +080012954 if (osd_hw.scale[OSD2].v_enable &&
12955 osd_hw.scaledata[OSD2].y_start > 0 &&
12956 osd_hw.scaledata[OSD2].y_end > 0) {
Googler4f18c0c2022-09-20 17:23:36 +080012957 y = y * osd_hw.scaledata[OSD2].y_end /
12958 osd_hw.scaledata[OSD2].y_start;
12959 }
12960 x += xstart;
12961 y += ystart;
12962 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
12963 if (osd_w >= osd_h)
12964 w_diff = osd_w - osd_h;
12965 else
12966 w_diff = 0;
12967 osd_hw.pandata[OSD2].x_start = w_diff;
12968 osd_hw.pandata[OSD2].x_end = osd_w - 1;
12969 osd_hw.pandata[OSD2].y_start = 0;
12970 osd_hw.pandata[OSD2].y_end = osd_h - 1;
12971 x -= osd_w;
12972 y -= osd_h;
12973 osd_log_dbg(MODULE_CURSOR, "x=%d,y=%d\n", x, y);
12974 }
12975 /*
12976 * Use pandata to show a partial cursor when it is at the edge because
12977 * the registers can't have negative values and because we need to
12978 * manually clip the cursor when it is past the edge. The edge is
12979 * hardcoded to the OSD0 area.
12980 */
12981 osd_hw.dispdata[OSD2].x_start = x;
12982 osd_hw.dispdata[OSD2].y_start = y;
12983 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
12984 if (x < disp_tmp.x_start) {
12985 /* if negative position, set osd x pan. */
12986 if ((disp_tmp.x_start - x) < osd_w) {
12987 osd_hw.pandata[OSD2].x_start =
12988 w_diff;
12989 osd_hw.pandata[OSD2].x_end =
12990 osd_w - 1 - (disp_tmp.x_start - x);
12991 }
12992 /* set osd x to disp_tmp.x_start */
12993 osd_hw.dispdata[OSD2].x_start = disp_tmp.x_start;
12994 }
12995 if (y < disp_tmp.y_start) {
12996 /* if negative position, set osd y pan. */
12997 if ((disp_tmp.y_start - y) < osd_h) {
12998 osd_hw.pandata[OSD2].y_start = 0;
12999 osd_hw.pandata[OSD2].y_end =
13000 osd_h - 1 - (disp_tmp.y_start - y);
13001 }
13002 /* set osd y to disp_tmp.y_start */
13003 osd_hw.dispdata[OSD2].y_start = disp_tmp.y_start;
13004 }
13005 } else {
13006 if (x < disp_tmp.x_start) {
13007 /* if negative position, set osd to 0,y and pan. */
13008 if ((disp_tmp.x_start - x) < osd_w) {
13009 osd_hw.pandata[OSD2].x_start =
13010 disp_tmp.x_start - x;
13011 osd_hw.pandata[OSD2].x_end = osd_w - 1;
13012 }
13013 osd_hw.dispdata[OSD2].x_start = 0;
13014 } else {
13015 osd_hw.pandata[OSD2].x_start = 0;
13016 if (x + osd_w > disp_tmp.x_end) {
13017 /*
13018 * if past positive edge,
13019 * set osd to inside of the edge and pan.
13020 */
13021 if (x < disp_tmp.x_end)
13022 osd_hw.pandata[OSD2].x_end =
13023 disp_tmp.x_end - x;
Googler9398cc32022-12-02 17:21:52 +080013024 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013025 osd_hw.pandata[OSD2].x_end = osd_w - 1;
Googler9398cc32022-12-02 17:21:52 +080013026 }
Googler4f18c0c2022-09-20 17:23:36 +080013027 }
13028 if (y < disp_tmp.y_start) {
13029 if ((disp_tmp.y_start - y) < osd_h) {
13030 osd_hw.pandata[OSD2].y_start =
13031 disp_tmp.y_start - y;
13032 osd_hw.pandata[OSD2].y_end = osd_h - 1;
13033 }
13034 osd_hw.dispdata[OSD2].y_start = 0;
13035 } else {
13036 osd_hw.pandata[OSD2].y_start = 0;
13037 if (y + osd_h > disp_tmp.y_end) {
13038 if (y < disp_tmp.y_end)
13039 osd_hw.pandata[OSD2].y_end =
13040 disp_tmp.y_end - y;
Googler9398cc32022-12-02 17:21:52 +080013041 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013042 osd_hw.pandata[OSD2].y_end = osd_h - 1;
Googler9398cc32022-12-02 17:21:52 +080013043 }
Googler4f18c0c2022-09-20 17:23:36 +080013044 }
13045 }
13046 osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start +
13047 osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start;
13048 osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start +
13049 osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start;
13050 add_to_update_list(OSD2, OSD_COLOR_MODE);
13051 add_to_update_list(OSD2, DISP_GEOMETRY);
13052 osd_log_dbg(MODULE_CURSOR, "dispdata: %d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +080013053 osd_hw.dispdata[OSD2].x_start, osd_hw.dispdata[OSD2].x_end,
13054 osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080013055}
13056
13057void osd_cursor_hw_no_scale(u32 index, s16 x, s16 y, s16 xstart, s16 ystart,
Googler9398cc32022-12-02 17:21:52 +080013058 u32 osd_w, u32 osd_h)
Googler4f18c0c2022-09-20 17:23:36 +080013059{
13060 struct pandata_s disp_tmp;
13061 struct vinfo_s *vinfo = NULL;
13062 int w = 0, h = 0;
13063 int w_diff = 0;
13064
13065 if (index != 1)
13066 return;
13067
13068 osd_log_dbg(MODULE_CURSOR, "cursor: x=%d, y=%d, x0=%d, y0=%d, w=%d, h=%d\n",
Googler9398cc32022-12-02 17:21:52 +080013069 x, y, xstart, ystart, osd_w, osd_h);
Googler4f18c0c2022-09-20 17:23:36 +080013070
13071 if (osd_hw.free_scale_mode[OSD1]) {
13072 if (osd_hw.free_scale_enable[OSD1])
13073 memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080013074 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +080013075 else
13076 memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080013077 sizeof(struct pandata_s));
13078 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013079 memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080013080 sizeof(struct pandata_s));
13081 }
Googler4f18c0c2022-09-20 17:23:36 +080013082
13083 if (osd_hw.field_out_en[VIU1]) {
13084 disp_tmp.y_start *= 2;
13085 disp_tmp.y_end *= 2;
13086 }
13087
13088 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
Googler9398cc32022-12-02 17:21:52 +080013089 #ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +080013090 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +080013091 #endif
13092 if (!vinfo || vinfo->mode == VMODE_INIT_NULL)
Googler4f18c0c2022-09-20 17:23:36 +080013093 return;
13094
13095 w = vinfo->width;
13096 h = vinfo->height;
13097
13098 x = w - x;
13099 y = h - y;
13100 }
13101
13102 x += xstart;
13103 y += ystart;
13104
13105 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
13106 if (osd_w >= osd_h)
13107 w_diff = osd_w - osd_h;
13108 else
13109 w_diff = 0;
13110 osd_hw.pandata[OSD2].x_start = w_diff;
13111 osd_hw.pandata[OSD2].x_end = osd_w - 1;
13112 osd_hw.pandata[OSD2].y_start = 0;
13113 osd_hw.pandata[OSD2].y_end = osd_h - 1;
13114 x -= osd_w;
13115 y -= osd_h;
13116 osd_log_dbg(MODULE_CURSOR, "x=%d,y=%d\n", x, y);
13117 }
Googler4f18c0c2022-09-20 17:23:36 +080013118 /*
13119 * Use pandata to show a partial cursor when it is at the edge because
13120 * the registers can't have negative values and because we need to
13121 * manually clip the cursor when it is past the edge. The edge is
13122 * hardcoded to the OSD0 area.
13123 */
13124 osd_hw.dispdata[OSD2].x_start = x;
13125 osd_hw.dispdata[OSD2].y_start = y;
13126 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
13127 if (x < disp_tmp.x_start) {
13128 /* if negative position, set osd x pan. */
13129 if ((disp_tmp.x_start - x) < osd_w) {
13130 osd_hw.pandata[OSD2].x_start =
13131 w_diff;
13132 osd_hw.pandata[OSD2].x_end =
13133 osd_w - 1 - (disp_tmp.x_start - x);
13134 }
13135 /* set osd x to disp_tmp.x_start */
13136 osd_hw.dispdata[OSD2].x_start = disp_tmp.x_start;
13137 }
13138 if (y < disp_tmp.y_start) {
13139 /* if negative position, set osd y pan. */
13140 if ((disp_tmp.y_start - y) < osd_h) {
13141 osd_hw.pandata[OSD2].y_start = 0;
13142 osd_hw.pandata[OSD2].y_end =
13143 osd_h - 1 - (disp_tmp.y_start - y);
13144 }
13145 /* set osd y to disp_tmp.y_start */
13146 osd_hw.dispdata[OSD2].y_start = disp_tmp.y_start;
13147 }
13148 } else {
13149 if (x < disp_tmp.x_start) {
13150 /* if negative position, set osd to 0,y and pan. */
13151 if ((disp_tmp.x_start - x) < osd_w) {
13152 osd_hw.pandata[OSD2].x_start =
13153 disp_tmp.x_start - x;
13154 osd_hw.pandata[OSD2].x_end = osd_w - 1;
13155 }
13156 osd_hw.dispdata[OSD2].x_start = 0;
13157 } else {
13158 osd_hw.pandata[OSD2].x_start = 0;
13159 if (x + osd_w > disp_tmp.x_end) {
13160 /*
13161 * if past positive edge,
13162 * set osd to inside of the edge and pan.
13163 */
13164 if (x < disp_tmp.x_end)
13165 osd_hw.pandata[OSD2].x_end =
13166 disp_tmp.x_end - x;
Googler9398cc32022-12-02 17:21:52 +080013167 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013168 osd_hw.pandata[OSD2].x_end = osd_w - 1;
Googler9398cc32022-12-02 17:21:52 +080013169 }
Googler4f18c0c2022-09-20 17:23:36 +080013170 }
13171 if (y < disp_tmp.y_start) {
13172 if ((disp_tmp.y_start - y) < osd_h) {
13173 osd_hw.pandata[OSD2].y_start =
13174 disp_tmp.y_start - y;
13175 osd_hw.pandata[OSD2].y_end = osd_h - 1;
13176 }
13177 osd_hw.dispdata[OSD2].y_start = 0;
13178 } else {
13179 osd_hw.pandata[OSD2].y_start = 0;
13180 if (y + osd_h > disp_tmp.y_end) {
13181 if (y < disp_tmp.y_end)
13182 osd_hw.pandata[OSD2].y_end =
13183 disp_tmp.y_end - y;
Googler9398cc32022-12-02 17:21:52 +080013184 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013185 osd_hw.pandata[OSD2].y_end = osd_h - 1;
Googler9398cc32022-12-02 17:21:52 +080013186 }
Googler4f18c0c2022-09-20 17:23:36 +080013187 }
13188 }
13189
13190 if (osd_hw.field_out_en[VIU1])
13191 osd_hw.dispdata[OSD2].y_start /= 2;
13192
13193 osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start +
13194 osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start;
13195 osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start +
13196 osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start;
13197 add_to_update_list(OSD2, OSD_COLOR_MODE);
13198 add_to_update_list(OSD2, DISP_GEOMETRY);
13199 osd_log_dbg(MODULE_CURSOR, "dispdata: %d,%d,%d,%d\n",
Googler9398cc32022-12-02 17:21:52 +080013200 osd_hw.dispdata[OSD2].x_start, osd_hw.dispdata[OSD2].x_end,
13201 osd_hw.dispdata[OSD2].y_start, osd_hw.dispdata[OSD2].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080013202}
13203
13204void osd_suspend_hw(void)
13205{
Googler9726be62022-12-14 05:53:31 +000013206 wait_vsync_wakeup();
13207 wait_vsync_wakeup_viu2();
Googler9398cc32022-12-02 17:21:52 +080013208 wait_vsync_wakeup_viu3();
13209 wait_rdma_done_wakeup();
13210 wait_rdma_done_wakeup_viu2();
13211 wait_rdma_done_wakeup_viu3();
Googler4f18c0c2022-09-20 17:23:36 +080013212 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
13213 osd_hw.reg_status_save =
13214 osd_reg_read(VPP_MISC) & OSD_RELATIVE_BITS;
13215 osd_vpp_misc &= ~OSD_RELATIVE_BITS;
13216 notify_to_amvideo();
13217 osd_reg_clr_mask(VPP_MISC, OSD_RELATIVE_BITS);
13218 /* VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, OSD_RELATIVE_BITS); */
13219 } else {
13220 int i = 0;
Googler9398cc32022-12-02 17:21:52 +080013221
Googler4f18c0c2022-09-20 17:23:36 +080013222 spin_lock_irqsave(&osd_lock, lock_flags);
13223 suspend_flag = true;
13224 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) {
13225 if (osd_hw.enable[i]) {
13226 osd_hw.enable_save[i] = ENABLE;
13227 osd_hw.enable[i] = DISABLE;
Googler9726be62022-12-14 05:53:31 +000013228 /* if display2 mode is set to null or invalid */
13229 if (osd_hw.osd_meson_dev.has_viu2 &&
13230 i == osd_hw.osd_meson_dev.viu2_index) {
13231 struct vinfo_s *vinfo = NULL;
13232
13233 vinfo = get_current_vinfo2();
Googler9398cc32022-12-02 17:21:52 +080013234 if (vinfo && vinfo->name &&
Googler9726be62022-12-14 05:53:31 +000013235 (!strncmp(vinfo->name, "null", 4) ||
13236 !strncmp(vinfo->name, "invalid", 7)
13237 )
13238 )
13239 continue;
13240 }
Googler4f18c0c2022-09-20 17:23:36 +080013241 osd_hw.reg[OSD_ENABLE]
13242 .update_func(i);
Googler9398cc32022-12-02 17:21:52 +080013243 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013244 osd_hw.enable_save[i] = DISABLE;
Googler9398cc32022-12-02 17:21:52 +080013245 }
Googler4f18c0c2022-09-20 17:23:36 +080013246 }
13247 osd_hw.reg_status_save =
13248 osd_reg_read(VIU_OSD_BLEND_CTRL);
13249 osd_hw.reg_status_save1 =
13250 osd_reg_read(OSD1_BLEND_SRC_CTRL);
13251
13252 osd_hw.reg_status_save3 =
13253 osd_reg_read(VPP_RDARB_REQEN_SLV);
Googler9398cc32022-12-02 17:21:52 +080013254 if (!osd_dev_hw.multi_afbc_core)
13255 osd_hw.reg_status_save4 =
13256 osd_reg_read(VPU_MAFBC_SURFACE_CFG);
Googler4f18c0c2022-09-20 17:23:36 +080013257 osd_reg_clr_mask(VIU_OSD_BLEND_CTRL, 0xf0000);
13258 osd_reg_clr_mask(OSD1_BLEND_SRC_CTRL, 0xf0f);
13259 if (!enable_vd_zorder) {
13260 osd_hw.reg_status_save2 =
13261 osd_reg_read(OSD2_BLEND_SRC_CTRL);
Googler9398cc32022-12-02 17:21:52 +080013262 osd_reg_clr_mask(OSD2_BLEND_SRC_CTRL, 0xf0f);
Googler4f18c0c2022-09-20 17:23:36 +080013263 }
13264 osd_reg_clr_mask(VPP_RDARB_REQEN_SLV,
Googler9398cc32022-12-02 17:21:52 +080013265 rdarb_reqen_slv);
13266 if (!osd_dev_hw.multi_afbc_core) {
13267 osd_reg_write(VPU_MAFBC_SURFACE_CFG, 0);
13268 osd_reg_write(VPU_MAFBC_COMMAND, 1);
13269 }
Googler4f18c0c2022-09-20 17:23:36 +080013270 spin_unlock_irqrestore(&osd_lock, lock_flags);
13271
13272 if (supsend_delay)
13273 mdelay(supsend_delay);
13274 }
13275 osd_log_info("osd_suspended\n");
13276}
13277
13278void osd_resume_hw(void)
13279{
13280 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
13281 if (osd_hw.reg_status_save &
13282 (VPP_OSD1_POSTBLEND | VPP_OSD2_POSTBLEND))
13283 osd_hw.reg_status_save |= VPP_POSTBLEND_EN;
13284 osd_vpp_misc = osd_hw.reg_status_save & OSD_RELATIVE_BITS;
13285 notify_to_amvideo();
13286 osd_reg_set_mask(VPP_MISC, osd_hw.reg_status_save);
13287 if (osd_hw.enable[OSD2] == ENABLE) {
13288 osd_vpp_misc |= VPP_OSD2_POSTBLEND;
Googler9398cc32022-12-02 17:21:52 +080013289 osd_reg_set_mask(VIU_OSD2_CTRL_STAT,
13290 1 << 0);
13291 osd_reg_set_mask(VPP_MISC,
13292 VPP_OSD2_POSTBLEND
13293 | VPP_POSTBLEND_EN);
Googler4f18c0c2022-09-20 17:23:36 +080013294 } else {
13295 osd_vpp_misc &= ~VPP_OSD2_POSTBLEND;
13296 osd_reg_clr_mask(VPP_MISC,
Googler9398cc32022-12-02 17:21:52 +080013297 VPP_OSD2_POSTBLEND);
13298 osd_reg_clr_mask(VIU_OSD2_CTRL_STAT,
13299 1 << 0);
Googler4f18c0c2022-09-20 17:23:36 +080013300 }
13301 notify_to_amvideo();
13302 } else {
13303 int i = 0;
Googler9398cc32022-12-02 17:21:52 +080013304
Googler4f18c0c2022-09-20 17:23:36 +080013305 spin_lock_irqsave(&osd_lock, lock_flags);
13306 suspend_flag = false;
13307 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++) {
13308 if (osd_hw.enable_save[i]) {
13309 osd_hw.enable[i] = ENABLE;
Googler9726be62022-12-14 05:53:31 +000013310 /* if display2 mode is set to null or invalid */
13311 if (osd_hw.osd_meson_dev.has_viu2 &&
13312 i == osd_hw.osd_meson_dev.viu2_index) {
13313 struct vinfo_s *vinfo = NULL;
13314
13315 vinfo = get_current_vinfo2();
Googler9398cc32022-12-02 17:21:52 +080013316 if (vinfo && vinfo->name &&
Googler9726be62022-12-14 05:53:31 +000013317 (!strncmp(vinfo->name, "null", 4) ||
13318 !strncmp(vinfo->name, "invalid", 7)
13319 )
13320 )
13321 continue;
13322 }
Googler4f18c0c2022-09-20 17:23:36 +080013323 osd_hw.reg[OSD_ENABLE]
13324 .update_func(i);
13325 }
13326 }
13327 osd_reg_write(VIU_OSD_BLEND_CTRL,
Googler9398cc32022-12-02 17:21:52 +080013328 osd_hw.reg_status_save);
Googler4f18c0c2022-09-20 17:23:36 +080013329 osd_reg_write(OSD1_BLEND_SRC_CTRL,
Googler9398cc32022-12-02 17:21:52 +080013330 osd_hw.reg_status_save1);
Googler4f18c0c2022-09-20 17:23:36 +080013331 if (!enable_vd_zorder)
13332 osd_reg_write(OSD2_BLEND_SRC_CTRL,
Googler9398cc32022-12-02 17:21:52 +080013333 osd_hw.reg_status_save2);
Googler4f18c0c2022-09-20 17:23:36 +080013334 osd_reg_write(VPP_RDARB_REQEN_SLV,
Googler9398cc32022-12-02 17:21:52 +080013335 osd_hw.reg_status_save3);
13336 if (!osd_dev_hw.multi_afbc_core)
13337 osd_reg_write(VPU_MAFBC_SURFACE_CFG,
13338 osd_hw.reg_status_save4);
Googler9726be62022-12-14 05:53:31 +000013339 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++)
13340 osd_hw.osd_afbcd[i].afbc_start = 0;
Googler4f18c0c2022-09-20 17:23:36 +080013341 spin_unlock_irqrestore(&osd_lock, lock_flags);
13342 }
Googler9726be62022-12-14 05:53:31 +000013343 osd_log_out = 1;
Googler4f18c0c2022-09-20 17:23:36 +080013344 osd_log_info("osd_resumed\n");
13345}
13346
13347void osd_shutdown_hw(void)
13348{
Googler9726be62022-12-14 05:53:31 +000013349 wait_vsync_wakeup();
13350 wait_vsync_wakeup_viu2();
Googler9398cc32022-12-02 17:21:52 +080013351 wait_vsync_wakeup_viu3();
13352 wait_rdma_done_wakeup();
13353 wait_rdma_done_wakeup_viu2();
13354 wait_rdma_done_wakeup_viu3();
Googler4f18c0c2022-09-20 17:23:36 +080013355#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
13356 if (osd_hw.osd_meson_dev.has_rdma)
13357 enable_rdma(0);
13358#endif
Googler9398cc32022-12-02 17:21:52 +080013359 if (osd_hw.hw_rdma_en) {
13360 osd_rdma_enable(VPU_VPP0, 0);
13361 if (osd_hw.osd_meson_dev.has_vpp1 &&
13362 osd_hw.display_dev_cnt == 2)
13363 osd_rdma_enable(VPU_VPP1, 0);
13364 if (osd_hw.osd_meson_dev.has_vpp2 &&
13365 osd_hw.display_dev_cnt == 3)
13366 osd_rdma_enable(VPU_VPP2, 0);
13367 }
Googler4f18c0c2022-09-20 17:23:36 +080013368 pr_info("osd_shutdown\n");
13369}
13370
13371#ifdef CONFIG_HIBERNATION
13372static unsigned int fb0_cfg_w0_save;
13373static u32 __nosavedata free_scale_enable[HW_OSD_COUNT];
13374
13375void osd_realdata_save_hw(void)
13376{
13377 int i;
13378
13379 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++)
13380 free_scale_enable[i] = osd_hw.free_scale_enable[i];
13381}
13382
13383void osd_realdata_restore_hw(void)
13384{
13385 int i;
13386
13387 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++)
13388 osd_hw.free_scale_enable[i] = free_scale_enable[i];
13389}
13390
13391void osd_freeze_hw(void)
13392{
13393#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
13394 if (osd_hw.osd_meson_dev.has_rdma)
13395 enable_rdma(0);
13396#endif
13397 if (osd_hw.hw_rdma_en) {
Googler9398cc32022-12-02 17:21:52 +080013398 osd_rdma_enable(VPU_VPP0, 0);
13399 if (osd_hw.osd_meson_dev.has_vpp1 &&
13400 osd_hw.display_dev_cnt == 2)
13401 osd_rdma_enable(VPU_VPP1, 0);
13402 if (osd_hw.osd_meson_dev.has_vpp2 &&
13403 osd_hw.display_dev_cnt == 3)
13404 osd_rdma_enable(VPU_VPP2, 0);
Googler4f18c0c2022-09-20 17:23:36 +080013405 if (get_backup_reg(VIU_OSD1_BLK0_CFG_W0,
Googler9398cc32022-12-02 17:21:52 +080013406 &fb0_cfg_w0_save) != 0)
Googler4f18c0c2022-09-20 17:23:36 +080013407 fb0_cfg_w0_save =
13408 osd_reg_read(VIU_OSD1_BLK0_CFG_W0);
Googler9398cc32022-12-02 17:21:52 +080013409 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013410 fb0_cfg_w0_save = osd_reg_read(VIU_OSD1_BLK0_CFG_W0);
Googler9398cc32022-12-02 17:21:52 +080013411 }
Googler4f18c0c2022-09-20 17:23:36 +080013412 pr_debug("osd_freezed\n");
13413}
Googler9398cc32022-12-02 17:21:52 +080013414
Googler4f18c0c2022-09-20 17:23:36 +080013415void osd_thaw_hw(void)
13416{
13417 pr_debug("osd_thawed\n");
Googler9398cc32022-12-02 17:21:52 +080013418 if (osd_hw.hw_rdma_en) {
13419 osd_rdma_enable(VPU_VPP0, 2);
13420 if (osd_hw.osd_meson_dev.has_vpp1 &&
13421 osd_hw.display_dev_cnt == 2)
13422 osd_rdma_enable(VPU_VPP1, 2);
13423 if (osd_hw.osd_meson_dev.has_vpp2 &&
13424 osd_hw.display_dev_cnt == 3)
13425 osd_rdma_enable(VPU_VPP2, 2);
13426 }
Googler4f18c0c2022-09-20 17:23:36 +080013427#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
13428 if (osd_hw.osd_meson_dev.has_rdma)
13429 enable_rdma(1);
13430#endif
13431}
Googler9398cc32022-12-02 17:21:52 +080013432
Googler4f18c0c2022-09-20 17:23:36 +080013433void osd_restore_hw(void)
13434{
13435 int i;
13436
13437 osd_reg_write(VIU_OSD1_BLK0_CFG_W0, fb0_cfg_w0_save);
Googler9398cc32022-12-02 17:21:52 +080013438 if (osd_hw.hw_rdma_en) {
13439 osd_rdma_enable(VPU_VPP0, 2);
13440 if (osd_hw.osd_meson_dev.has_vpp1 &&
13441 osd_hw.display_dev_cnt == 2)
13442 osd_rdma_enable(VPU_VPP1, 2);
13443 if (osd_hw.osd_meson_dev.has_vpp2 &&
13444 osd_hw.display_dev_cnt == 3)
13445 osd_rdma_enable(VPU_VPP2, 2);
13446 }
Googler4f18c0c2022-09-20 17:23:36 +080013447#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
13448 if (osd_hw.osd_meson_dev.has_rdma)
13449 enable_rdma(1);
13450#endif
13451
Googler9398cc32022-12-02 17:21:52 +080013452 if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) {
Googler4f18c0c2022-09-20 17:23:36 +080013453 osd_update_phy_addr(0);
Googler9398cc32022-12-02 17:21:52 +080013454 } else if (osd_hw.osd_meson_dev.mif_linear) {
Googler38bda472022-08-19 10:07:08 -070013455 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++)
Googler9398cc32022-12-02 17:21:52 +080013456 osd_update_mif_linear_addr(i);
13457 } else {
13458#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
13459
13460 for (i = 0; i < osd_hw.osd_meson_dev.osd_count; i++)
13461 canvas_config(osd_hw.fb_gem[i].canvas_idx,
13462 osd_hw.fb_gem[i].addr,
13463 CANVAS_ALIGNED(osd_hw.fb_gem[i].width),
13464 osd_hw.fb_gem[i].height,
13465 CANVAS_ADDR_NOWRAP,
13466 CANVAS_BLKMODE_LINEAR);
Googler012a81c2022-09-15 14:55:24 +080013467#endif
Googler9398cc32022-12-02 17:21:52 +080013468 }
Googler4f18c0c2022-09-20 17:23:36 +080013469 pr_debug("osd_restored\n");
13470}
13471#endif
13472
13473int osd_get_logo_index(void)
13474{
13475 return osd_logo_index;
13476}
13477
13478void osd_set_logo_index(int index)
13479{
13480 osd_logo_index = index;
13481}
13482
13483void osd_get_hw_para(struct hw_para_s **para)
13484{
13485 *para = &osd_hw;
13486}
Googler9398cc32022-12-02 17:21:52 +080013487
Googler4f18c0c2022-09-20 17:23:36 +080013488void osd_get_blending_para(struct hw_osd_blending_s **para)
13489{
13490 *para = &osd_blending;
13491}
Googler9398cc32022-12-02 17:21:52 +080013492
13493void osd_backup_screen_info(u32 index,
13494 unsigned long screen_base,
13495 unsigned long screen_size)
Googler4f18c0c2022-09-20 17:23:36 +080013496{
13497 osd_hw.screen_base_backup[index] = screen_base;
13498 osd_hw.screen_size_backup[index] = screen_size;
13499}
13500
Googler9398cc32022-12-02 17:21:52 +080013501void osd_get_screen_info(u32 index,
13502 char __iomem **screen_base,
13503 unsigned long *screen_size)
Googler4f18c0c2022-09-20 17:23:36 +080013504{
Googler9398cc32022-12-02 17:21:52 +080013505 if (index >= OSD_MAX)
13506 return;
Googler4f18c0c2022-09-20 17:23:36 +080013507 *screen_base = (char __iomem *)osd_hw.screen_base[index];
13508 *screen_size = osd_hw.screen_size[index];
13509}
13510
Googler9398cc32022-12-02 17:21:52 +080013511void osd_get_fence_count(u32 index, u32 *fence_cnt, u32 *timeline_cnt)
13512{
13513#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
13514 u32 output_index;
13515 struct sync_timeline *tl = NULL;
13516#endif
13517
13518 if (index >= OSD_MAX || !fence_cnt || !timeline_cnt)
13519 return;
13520
13521#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
13522 output_index = get_output_device_id(index);
13523 tl = (struct sync_timeline *)osd_timeline[output_index];
13524
13525 *fence_cnt = cur_streamline_val[output_index];
13526 *timeline_cnt = tl ? tl->value : 0;
13527#else
13528 *fence_cnt = 0;
13529 *timeline_cnt = 0;
13530#endif
13531}
13532
Googler4f18c0c2022-09-20 17:23:36 +080013533int get_vmap_addr(u32 index, u8 __iomem **buf)
13534{
13535 unsigned long total_size;
13536 ulong phys;
13537 u32 offset, npages;
13538 struct page **pages = NULL;
13539 pgprot_t pgprot;
13540 static u8 *vaddr;
13541 int i;
13542
13543 total_size = osd_hw.screen_size[index];
13544
13545 npages = PAGE_ALIGN(total_size) / PAGE_SIZE;
13546 phys = osd_hw.screen_base[index];
13547 offset = phys & ~PAGE_MASK;
13548 if (offset)
13549 npages++;
13550 pages = vmalloc(sizeof(struct page *) * npages);
13551 if (!pages)
13552 return -ENOMEM;
13553 for (i = 0; i < npages; i++) {
13554 pages[i] = phys_to_page(phys);
13555 phys += PAGE_SIZE;
13556 }
13557 /*nocache*/
13558 pgprot = pgprot_writecombine(PAGE_KERNEL);
13559 if (vaddr) {
13560 /* unmap prevois vaddr */
13561 vunmap(vaddr);
13562 vaddr = NULL;
13563 }
13564 vaddr = vmap(pages, npages, VM_MAP, pgprot);
13565 if (!vaddr) {
13566 pr_err("the phy(%lx) vmaped fail, size: %d\n",
Googler9398cc32022-12-02 17:21:52 +080013567 phys, npages << PAGE_SHIFT);
Googler4f18c0c2022-09-20 17:23:36 +080013568 vfree(pages);
13569 return -ENOMEM;
13570 }
13571 vfree(pages);
Googler9398cc32022-12-02 17:21:52 +080013572 *buf = (u8 __iomem *)(vaddr);
Googler4f18c0c2022-09-20 17:23:36 +080013573 return osd_hw.screen_size[index];
13574}
Googler4f18c0c2022-09-20 17:23:36 +080013575
Googler4f18c0c2022-09-20 17:23:36 +080013576int osd_set_clear(u32 index)
13577{
13578 unsigned long total_size;
13579 ulong phys;
13580 u32 offset, npages;
13581 struct page **pages = NULL;
13582 pgprot_t pgprot;
13583 static u8 *vaddr;
13584 u8 __iomem *dst;
13585 int i, c, count, cnt = 0;
13586
13587 total_size = osd_hw.screen_size[index];
13588 npages = PAGE_ALIGN(total_size) / PAGE_SIZE;
13589 phys = osd_hw.screen_base[index];
13590 offset = phys & (~PAGE_MASK);
13591 if (offset)
13592 npages++;
13593 pages = vmalloc(sizeof(struct page *) * npages);
13594 if (!pages)
13595 return -ENOMEM;
13596 for (i = 0; i < npages; i++) {
13597 pages[i] = phys_to_page(phys);
13598 phys += PAGE_SIZE;
13599 }
13600 /*nocache*/
13601 pgprot = pgprot_writecombine(PAGE_KERNEL);
13602
13603 vaddr = vmap(pages, npages, VM_MAP, pgprot);
13604 if (!vaddr) {
13605 pr_err("the phy(%lx) vmaped fail, size: %d\n",
Googler9398cc32022-12-02 17:21:52 +080013606 phys, npages << PAGE_SHIFT);
Googler4f18c0c2022-09-20 17:23:36 +080013607 vfree(pages);
13608 return -ENOMEM;
13609 }
13610 vfree(pages);
Googler9398cc32022-12-02 17:21:52 +080013611 dst = (u8 __iomem *)(vaddr);
Googler4f18c0c2022-09-20 17:23:36 +080013612
13613 count = total_size;
13614 while (count) {
13615 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
13616 memset(dst, 0, c);
13617 dst += c;
13618 cnt += c;
13619 count -= c;
13620 }
13621 if (vaddr) {
13622 /* unmap prevois vaddr */
13623 vunmap(vaddr);
13624 vaddr = NULL;
13625 }
13626
13627 return cnt;
13628}
13629
13630static const struct color_bit_define_s *convert_panel_format(u32 format)
13631{
13632 const struct color_bit_define_s *color = NULL;
13633
13634 format &= ~AFBC_EN;
13635 switch (format) {
13636 case COLOR_INDEX_02_PAL4:
13637 case COLOR_INDEX_04_PAL16:
13638 case COLOR_INDEX_08_PAL256:
13639 case COLOR_INDEX_16_655:
13640 case COLOR_INDEX_16_844:
13641 case COLOR_INDEX_16_6442:
13642 case COLOR_INDEX_16_4444_R:
13643 case COLOR_INDEX_16_4642_R:
13644 case COLOR_INDEX_16_1555_A:
13645 case COLOR_INDEX_16_4444_A:
13646 case COLOR_INDEX_16_565:
13647 case COLOR_INDEX_24_6666_A:
13648 case COLOR_INDEX_24_6666_R:
13649 case COLOR_INDEX_24_8565:
13650 case COLOR_INDEX_24_5658:
13651 case COLOR_INDEX_24_888_B:
13652 case COLOR_INDEX_24_RGB:
13653 case COLOR_INDEX_32_BGRX:
13654 case COLOR_INDEX_32_XBGR:
13655 case COLOR_INDEX_32_RGBX:
13656 case COLOR_INDEX_32_XRGB:
13657 case COLOR_INDEX_32_BGRA:
13658 case COLOR_INDEX_32_ABGR:
13659 case COLOR_INDEX_32_RGBA:
13660 case COLOR_INDEX_32_ARGB:
13661 case COLOR_INDEX_YUV_422:
13662 color = &default_color_format_array[format];
13663 break;
13664 }
13665 return color;
13666}
13667
13668static bool osd_direct_render(struct osd_plane_map_s *plane_map)
13669{
13670 u32 index = plane_map->plane_index;
13671 u32 phy_addr = plane_map->phy_addr;
13672 u32 width_src, width_dst, height_src, height_dst;
13673 u32 x_start, x_end, y_start, y_end;
13674 bool freescale_update = false;
13675 struct pandata_s freescale_dst[HW_OSD_COUNT];
13676 u32 output_index;
13677
13678 output_index = get_output_device_id(index);
13679 phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y;
13680 osd_hw.screen_base[index] = phy_addr;
13681 osd_hw.screen_size[index] =
13682 plane_map->byte_stride * plane_map->src_h;
13683 osd_log_dbg(MODULE_RENDER, "canvas_id=%x, phy_addr=%x\n",
Googler9398cc32022-12-02 17:21:52 +080013684 osd_hw.fb_gem[index].canvas_idx, phy_addr);
Googler4f18c0c2022-09-20 17:23:36 +080013685 if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) {
13686 osd_hw.fb_gem[index].addr = phy_addr;
13687 osd_hw.fb_gem[index].width = plane_map->byte_stride;
13688 osd_update_phy_addr(0);
Googler9398cc32022-12-02 17:21:52 +080013689 } else if (osd_hw.osd_meson_dev.mif_linear) {
13690 osd_update_mif_linear_addr(index);
Googler4f18c0c2022-09-20 17:23:36 +080013691 } else {
Googler9398cc32022-12-02 17:21:52 +080013692 #ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler4f18c0c2022-09-20 17:23:36 +080013693 canvas_config(osd_hw.fb_gem[index].canvas_idx,
Googler9398cc32022-12-02 17:21:52 +080013694 phy_addr,
13695 CANVAS_ALIGNED(plane_map->byte_stride),
13696 plane_map->src_h,
13697 CANVAS_ADDR_NOWRAP,
13698 CANVAS_BLKMODE_LINEAR);
13699 #endif
Googler4f18c0c2022-09-20 17:23:36 +080013700 }
13701 if (osd_hw.hwc_enable[output_index]) {
13702 /* just get para, need update via do_hwc */
13703 osd_hw.order[index] = plane_map->zorder;
13704 switch (plane_map->blend_mode) {
13705 case BLEND_MODE_PREMULTIPLIED:
13706 osd_hw.premult_en[index] = 1;
13707 break;
13708 case BLEND_MODE_COVERAGE:
13709 case BLEND_MODE_NONE:
13710 case BLEND_MODE_INVALID:
13711 osd_hw.premult_en[index] = 0;
13712 break;
13713 }
13714 //Todo: fence_map.plane_alpha
13715 osd_hw.osd_afbcd[index].inter_format =
13716 plane_map->afbc_inter_format & 0x7fffffff;
13717
13718 osd_hw.src_data[index].x = plane_map->src_x;
13719 osd_hw.src_data[index].y = plane_map->src_y;
13720 osd_hw.src_data[index].w = plane_map->src_w;
13721 osd_hw.src_data[index].h = plane_map->src_h;
13722
13723 osd_hw.dst_data[index].x = plane_map->dst_x;
13724 osd_hw.dst_data[index].y = plane_map->dst_y;
13725 osd_hw.dst_data[index].w = plane_map->dst_w;
13726 osd_hw.dst_data[index].h = plane_map->dst_h;
13727 osd_log_dbg2(MODULE_RENDER, "index=%d\n", index);
13728 osd_log_dbg2(MODULE_RENDER, "order=%d\n",
Googler9398cc32022-12-02 17:21:52 +080013729 osd_hw.order[index]);
Googler4f18c0c2022-09-20 17:23:36 +080013730 osd_log_dbg2(MODULE_RENDER, "premult_en=%d\n",
Googler9398cc32022-12-02 17:21:52 +080013731 osd_hw.premult_en[index]);
Googler4f18c0c2022-09-20 17:23:36 +080013732 osd_log_dbg2(MODULE_RENDER, "osd_afbcd_en=%d\n",
Googler9398cc32022-12-02 17:21:52 +080013733 osd_hw.osd_afbcd[index].enable);
Googler4f18c0c2022-09-20 17:23:36 +080013734 osd_log_dbg2(MODULE_RENDER, "osd_afbcd_inter_format=%d\n",
Googler9398cc32022-12-02 17:21:52 +080013735 osd_hw.osd_afbcd[index].inter_format);
Googler4f18c0c2022-09-20 17:23:36 +080013736 return 0;
13737 }
13738
13739 width_dst = osd_hw.free_dst_data_backup[index].x_end -
13740 osd_hw.free_dst_data_backup[index].x_start + 1;
13741 width_src = osd_hw.free_src_data_backup[index].x_end -
13742 osd_hw.free_src_data_backup[index].x_start + 1;
13743
13744 height_dst = osd_hw.free_dst_data_backup[index].y_end -
13745 osd_hw.free_dst_data_backup[index].y_start + 1;
13746 height_src = osd_hw.free_src_data_backup[index].y_end -
13747 osd_hw.free_src_data_backup[index].y_start + 1;
13748 osd_hw.free_scale_enable[index] = 1;
13749
13750 osd_hw.src_data[index].x = plane_map->src_x;
13751 osd_hw.src_data[index].y = plane_map->src_y;
13752 osd_hw.src_data[index].w = plane_map->src_w;
13753 osd_hw.src_data[index].h = plane_map->src_h;
13754
13755 if (osd_hw.free_scale_enable[index] ||
Googler9398cc32022-12-02 17:21:52 +080013756 width_src != width_dst ||
13757 height_src != height_dst ||
13758 plane_map->src_w != plane_map->dst_w ||
13759 plane_map->src_h != plane_map->dst_h) {
Googler4f18c0c2022-09-20 17:23:36 +080013760 osd_hw.free_scale[index].h_enable = 1;
13761 osd_hw.free_scale[index].v_enable = 1;
13762 osd_hw.free_scale_enable[index] = 0x10001;
13763 osd_hw.free_scale_mode[index] = 1;
13764 if (osd_hw.free_scale_enable[index] !=
13765 osd_hw.free_scale_enable_backup[index]) {
13766 /* Todo: */
13767 osd_set_scan_mode(index);
13768 freescale_update = true;
13769 }
13770
13771 osd_hw.pandata[index].x_start = plane_map->src_x;
13772 osd_hw.pandata[index].x_end =
13773 plane_map->src_x + plane_map->src_w - 1;
13774 osd_hw.pandata[index].y_start = 0;
13775 osd_hw.pandata[index].y_end = plane_map->src_h - 1;
13776
13777 freescale_dst[index].x_start =
13778 osd_hw.free_dst_data_backup[index].x_start +
13779 (plane_map->dst_x * width_dst) / width_src;
13780 freescale_dst[index].x_end =
13781 osd_hw.free_dst_data_backup[index].x_start +
13782 ((plane_map->dst_x + plane_map->dst_w) *
13783 width_dst) / width_src - 1;
13784
13785 freescale_dst[index].y_start =
13786 osd_hw.free_dst_data_backup[index].y_start +
13787 (plane_map->dst_y * height_dst) / height_src;
13788 freescale_dst[index].y_end =
13789 osd_hw.free_dst_data_backup[index].y_start +
13790 ((plane_map->dst_y + plane_map->dst_h) *
13791 height_dst) / height_src - 1;
13792 if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
13793 x_start = osd_hw.vinfo_width[output_index]
13794 - freescale_dst[index].x_end - 1;
13795 y_start = osd_hw.vinfo_height[output_index]
13796 - freescale_dst[index].y_end - 1;
13797 x_end = osd_hw.vinfo_width[output_index]
13798 - freescale_dst[index].x_start - 1;
13799 y_end = osd_hw.vinfo_height[output_index]
13800 - freescale_dst[index].y_start - 1;
13801 freescale_dst[index].x_start = x_start;
13802 freescale_dst[index].y_start = y_start;
13803 freescale_dst[index].x_end = x_end;
13804 freescale_dst[index].y_end = y_end;
13805 } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
13806 x_start = osd_hw.vinfo_width[output_index]
13807 - freescale_dst[index].x_end - 1;
13808 x_end = osd_hw.vinfo_width[output_index]
13809 - freescale_dst[index].x_start - 1;
13810 freescale_dst[index].x_start = x_start;
13811 freescale_dst[index].x_end = x_end;
13812
13813 } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
13814 y_start = osd_hw.vinfo_height[output_index]
13815 - freescale_dst[index].y_end - 1;
13816 y_end = osd_hw.vinfo_height[output_index]
13817 - freescale_dst[index].y_start - 1;
13818 freescale_dst[index].y_start = y_start;
13819 freescale_dst[index].y_end = y_end;
13820 }
Googler9398cc32022-12-02 17:21:52 +080013821 if (memcmp(&osd_hw.free_src_data[index],
13822 &osd_hw.pandata[index],
13823 sizeof(struct pandata_s)) != 0 ||
13824 memcmp(&osd_hw.free_dst_data[index],
13825 &freescale_dst[index],
13826 sizeof(struct pandata_s)) != 0) {
13827 memcpy(&osd_hw.free_src_data[index],
13828 &osd_hw.pandata[index],
13829 sizeof(struct pandata_s));
13830 memcpy(&osd_hw.free_dst_data[index],
13831 &freescale_dst[index],
Googler4f18c0c2022-09-20 17:23:36 +080013832 sizeof(struct pandata_s));
13833 freescale_update = true;
13834 osd_hw.dst_data[index].x =
13835 osd_hw.free_dst_data[index].x_start;
13836 osd_hw.dst_data[index].y =
13837 osd_hw.free_dst_data[index].x_start;
13838 osd_hw.dst_data[index].w =
13839 osd_hw.free_dst_data[index].x_end -
13840 osd_hw.free_dst_data[index].x_start + 1;
13841 osd_hw.dst_data[index].h =
13842 osd_hw.free_dst_data[index].y_end -
13843 osd_hw.free_dst_data[index].y_start + 1;
Googler9398cc32022-12-02 17:21:52 +080013844
Googler9726be62022-12-14 05:53:31 +000013845 if ((height_dst != height_src ||
13846 width_dst != width_src) &&
13847 osd_hw.free_dst_data[index].y_end <
13848 osd_hw.vinfo_height[output_index] - 1)
Googler4f18c0c2022-09-20 17:23:36 +080013849 osd_set_dummy_data(index, 0);
13850 else
13851 osd_set_dummy_data(index, 0xff);
13852 }
13853 osd_log_dbg2(MODULE_RENDER,
Googler9398cc32022-12-02 17:21:52 +080013854 "pandata x=%d,x_end=%d,y=%d,y_end=%d\n",
13855 osd_hw.pandata[index].x_start,
13856 osd_hw.pandata[index].x_end,
13857 osd_hw.pandata[index].y_start,
13858 osd_hw.pandata[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080013859 osd_log_dbg2(MODULE_RENDER,
Googler9398cc32022-12-02 17:21:52 +080013860 "plane_map:src_x=%d,src_y=%d,src_w=%d,src_h=%d\n",
13861 plane_map->src_x,
13862 plane_map->src_y,
13863 plane_map->src_w,
13864 plane_map->src_h);
Googler4f18c0c2022-09-20 17:23:36 +080013865 osd_log_dbg2(MODULE_RENDER,
Googler9398cc32022-12-02 17:21:52 +080013866 "fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d\n",
13867 plane_map->dst_x,
13868 plane_map->dst_y,
13869 plane_map->dst_w,
13870 plane_map->dst_h);
Googler4f18c0c2022-09-20 17:23:36 +080013871 } else {
13872 osd_hw.pandata[index].x_start = 0;
13873 osd_hw.pandata[index].x_end = plane_map->src_w - 1;
13874 osd_hw.pandata[index].y_start = 0;
13875 osd_hw.pandata[index].y_end = plane_map->src_h - 1;
13876
13877 osd_hw.dispdata[index].x_start = plane_map->dst_x;
13878 osd_hw.dispdata[index].x_end =
13879 plane_map->dst_x + plane_map->dst_w - 1;
13880 osd_hw.dispdata[index].y_start = plane_map->dst_y;
13881 osd_hw.dispdata[index].y_end =
13882 plane_map->dst_y + plane_map->dst_h - 1;
13883 if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
13884 x_start = osd_hw.vinfo_width[output_index]
13885 - osd_hw.dispdata[index].x_end - 1;
13886 y_start = osd_hw.vinfo_height[output_index]
13887 - osd_hw.dispdata[index].y_end - 1;
13888 x_end = osd_hw.vinfo_width[output_index]
13889 - osd_hw.dispdata[index].x_start - 1;
13890 y_end = osd_hw.vinfo_height[output_index]
13891 - osd_hw.dispdata[index].y_start - 1;
13892 osd_hw.dispdata[index].x_start = x_start;
13893 osd_hw.dispdata[index].y_start = y_start;
13894 osd_hw.dispdata[index].x_end = x_end;
13895 osd_hw.dispdata[index].y_end = y_end;
13896 } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
13897 x_start = osd_hw.vinfo_width[output_index]
13898 - osd_hw.dispdata[index].x_end - 1;
13899 x_end = osd_hw.vinfo_width[output_index]
13900 - osd_hw.dispdata[index].x_start - 1;
13901 osd_hw.dispdata[index].x_start = x_start;
13902 osd_hw.dispdata[index].x_end = x_end;
13903
13904 } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
13905 y_start = osd_hw.vinfo_height[output_index]
13906 - osd_hw.dispdata[index].y_end - 1;
13907 y_end = osd_hw.vinfo_height[output_index]
13908 - osd_hw.dispdata[index].y_start - 1;
13909 osd_hw.dispdata[index].y_start = y_start;
13910 osd_hw.dispdata[index].y_end = y_end;
13911 }
13912 osd_hw.dst_data[index].x =
13913 osd_hw.dispdata[index].x_start;
13914 osd_hw.dst_data[index].y =
13915 osd_hw.dispdata[index].x_start;
13916 osd_hw.dst_data[index].w =
13917 osd_hw.dispdata[index].x_end -
13918 osd_hw.dispdata[index].x_start + 1;
13919 osd_hw.dst_data[index].h =
13920 osd_hw.dispdata[index].y_end -
13921 osd_hw.dispdata[index].y_start + 1;
Googler4f18c0c2022-09-20 17:23:36 +080013922 }
13923 return freescale_update;
13924}
13925
13926static void osd_cursor_move(struct osd_plane_map_s *plane_map)
13927{
13928 u32 index = plane_map->plane_index;
13929 u32 phy_addr = plane_map->phy_addr;
13930 u32 x_start, x_end, y_start, y_end;
13931 u32 x, y;
13932 struct pandata_s disp_tmp;
13933 struct pandata_s free_dst_data_backup;
13934 u32 output_index;
13935
13936 if (index != OSD2)
13937 return;
13938 output_index = get_output_device_id(index);
13939 phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y;
13940 osd_hw.screen_base[index] = phy_addr;
13941 osd_hw.screen_size[index] =
13942 plane_map->byte_stride * plane_map->src_h;
Googler9398cc32022-12-02 17:21:52 +080013943#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
Googler4f18c0c2022-09-20 17:23:36 +080013944 canvas_config(osd_hw.fb_gem[index].canvas_idx,
Googler9398cc32022-12-02 17:21:52 +080013945 phy_addr,
13946 CANVAS_ALIGNED(plane_map->byte_stride),
13947 plane_map->src_h,
13948 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
13949#endif
Googler4f18c0c2022-09-20 17:23:36 +080013950 osd_hw.pandata[index].x_start = plane_map->src_x;
13951 osd_hw.pandata[index].x_end = plane_map->src_w - 1;
13952 osd_hw.pandata[index].y_start = plane_map->src_y;
13953 osd_hw.pandata[index].y_end = plane_map->src_h - 1;
13954
13955 if (osd_hw.free_scale_mode[OSD1]) {
13956 if (osd_hw.free_scale_enable[OSD1])
13957 memcpy(&disp_tmp, &osd_hw.cursor_dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080013958 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +080013959 else
13960 memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080013961 sizeof(struct pandata_s));
13962 } else {
Googler4f18c0c2022-09-20 17:23:36 +080013963 memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
Googler9398cc32022-12-02 17:21:52 +080013964 sizeof(struct pandata_s));
13965 }
Googler4f18c0c2022-09-20 17:23:36 +080013966 memcpy(&free_dst_data_backup,
Googler9398cc32022-12-02 17:21:52 +080013967 &osd_hw.free_dst_data_backup[OSD1],
13968 sizeof(struct pandata_s));
Googler4f18c0c2022-09-20 17:23:36 +080013969 x = plane_map->dst_x;
13970 y = plane_map->dst_y;
13971 if (osd_hw.free_src_data_backup[OSD1].x_end > 0 &&
Googler9398cc32022-12-02 17:21:52 +080013972 free_dst_data_backup.x_end > 0) {
Googler4f18c0c2022-09-20 17:23:36 +080013973 x = x * free_dst_data_backup.x_end /
13974 osd_hw.free_src_data_backup[OSD1].x_end;
13975 }
13976 if (osd_hw.free_src_data_backup[OSD1].y_end > 0 &&
Googler9398cc32022-12-02 17:21:52 +080013977 free_dst_data_backup.y_end > 0) {
Googler4f18c0c2022-09-20 17:23:36 +080013978 y = y * free_dst_data_backup.y_end /
13979 osd_hw.free_src_data_backup[OSD1].y_end;
13980 }
13981
13982 /*
13983 * Use pandata to show a partial cursor when it is at the edge because
13984 * the registers can't have negative values and because we need to
13985 * manually clip the cursor when it is past the edge. The edge is
13986 * hardcoded to the OSD0 area.
13987 */
13988 osd_hw.dispdata[OSD2].x_start = x;
13989 osd_hw.dispdata[OSD2].y_start = y;
13990 if (x < disp_tmp.x_start) {
13991 /* if negative position, set osd to 0,y and pan. */
13992 if ((disp_tmp.x_start - x) < plane_map->src_w) {
13993 osd_hw.pandata[OSD2].x_start = disp_tmp.x_start - x;
13994 osd_hw.pandata[OSD2].x_end = plane_map->src_w - 1;
13995 }
13996 osd_hw.dispdata[OSD2].x_start = 0;
13997 } else {
13998 osd_hw.pandata[OSD2].x_start = 0;
13999 if (x + plane_map->src_w > disp_tmp.x_end) {
14000 /*
14001 * if past positive edge,
14002 * set osd to inside of the edge and pan.
14003 */
14004 if (x < disp_tmp.x_end)
14005 osd_hw.pandata[OSD2].x_end = disp_tmp.x_end - x;
Googler9398cc32022-12-02 17:21:52 +080014006 } else {
Googler4f18c0c2022-09-20 17:23:36 +080014007 osd_hw.pandata[OSD2].x_end = plane_map->src_w - 1;
Googler9398cc32022-12-02 17:21:52 +080014008 }
Googler4f18c0c2022-09-20 17:23:36 +080014009 }
14010 if (y < disp_tmp.y_start) {
14011 if ((disp_tmp.y_start - y) < plane_map->src_h) {
14012 osd_hw.pandata[OSD2].y_start = disp_tmp.y_start - y;
14013 osd_hw.pandata[OSD2].y_end = plane_map->src_h - 1;
14014 }
14015 osd_hw.dispdata[OSD2].y_start = 0;
14016 } else {
14017 osd_hw.pandata[OSD2].y_start = 0;
14018 if (y + plane_map->src_h > disp_tmp.y_end) {
14019 if (y < disp_tmp.y_end)
14020 osd_hw.pandata[OSD2].y_end = disp_tmp.y_end - y;
Googler9398cc32022-12-02 17:21:52 +080014021 } else {
Googler4f18c0c2022-09-20 17:23:36 +080014022 osd_hw.pandata[OSD2].y_end = plane_map->src_h - 1;
Googler9398cc32022-12-02 17:21:52 +080014023 }
Googler4f18c0c2022-09-20 17:23:36 +080014024 }
14025 osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start +
14026 osd_hw.pandata[OSD2].x_end - osd_hw.pandata[OSD2].x_start;
14027 osd_hw.dispdata[OSD2].y_end = osd_hw.dispdata[OSD2].y_start +
14028 osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start;
14029
14030 if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
14031 x_start = osd_hw.vinfo_width[output_index]
14032 - osd_hw.dispdata[index].x_end - 1;
14033 y_start = osd_hw.vinfo_height[output_index]
14034 - osd_hw.dispdata[index].y_end - 1;
14035 x_end = osd_hw.vinfo_width[output_index]
14036 - osd_hw.dispdata[index].x_start - 1;
14037 y_end = osd_hw.vinfo_height[output_index]
14038 - osd_hw.dispdata[index].y_start - 1;
14039 osd_hw.dispdata[index].x_start = x_start;
14040 osd_hw.dispdata[index].y_start = y_start;
14041 osd_hw.dispdata[index].x_end = x_end;
14042 osd_hw.dispdata[index].y_end = y_end;
14043 } else if (osd_hw.osd_reverse[OSD2] == REVERSE_X) {
14044 x_start = osd_hw.vinfo_width[output_index]
14045 - osd_hw.dispdata[index].x_end - 1;
14046 x_end = osd_hw.vinfo_width[output_index]
14047 - osd_hw.dispdata[index].x_start - 1;
14048 osd_hw.dispdata[index].x_start = x_start;
14049 osd_hw.dispdata[index].x_end = x_end;
Googler9398cc32022-12-02 17:21:52 +080014050 } else if (osd_hw.osd_reverse[OSD2] == REVERSE_Y) {
Googler4f18c0c2022-09-20 17:23:36 +080014051 y_start = osd_hw.vinfo_height[output_index]
14052 - osd_hw.dispdata[index].y_end - 1;
14053 y_end = osd_hw.vinfo_height[output_index]
14054 - osd_hw.dispdata[index].y_start - 1;
14055 osd_hw.dispdata[index].y_start = y_start;
14056 osd_hw.dispdata[index].y_end = y_end;
14057 }
14058 osd_log_dbg2(MODULE_CURSOR,
Googler9398cc32022-12-02 17:21:52 +080014059 "plane_map:src_x=%d,src_y=%d,src_w=%d,src_h=%d\n",
14060 plane_map->src_x,
14061 plane_map->src_y,
14062 plane_map->src_w,
14063 plane_map->src_h);
Googler4f18c0c2022-09-20 17:23:36 +080014064 osd_log_dbg2(MODULE_CURSOR,
Googler9398cc32022-12-02 17:21:52 +080014065 "fence_map:dst_x=%d,dst_y=%d,dst_w=%d,dst_h=%d\n",
14066 plane_map->dst_x,
14067 plane_map->dst_y,
14068 plane_map->dst_w,
14069 plane_map->dst_h);
Googler4f18c0c2022-09-20 17:23:36 +080014070 osd_log_dbg2(MODULE_CURSOR,
Googler9398cc32022-12-02 17:21:52 +080014071 "cursor pandata x=%d,x_end=%d,y=%d,y_end=%d\n",
14072 osd_hw.pandata[index].x_start,
14073 osd_hw.pandata[index].x_end,
14074 osd_hw.pandata[index].y_start,
14075 osd_hw.pandata[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080014076 osd_log_dbg2(MODULE_CURSOR,
Googler9398cc32022-12-02 17:21:52 +080014077 "cursor dispdata x=%d,x_end=%d,y=%d,y_end=%d\n",
14078 osd_hw.dispdata[index].x_start,
14079 osd_hw.dispdata[index].x_end,
14080 osd_hw.dispdata[index].y_start,
14081 osd_hw.dispdata[index].y_end);
Googler4f18c0c2022-09-20 17:23:36 +080014082}
14083
14084void osd_page_flip(struct osd_plane_map_s *plane_map)
14085{
14086 u32 index = plane_map->plane_index;
14087 const struct color_bit_define_s *color = NULL;
14088 bool freescale_update = false;
14089 u32 osd_enable = 0;
14090 u32 format = 0;
14091 const struct vinfo_s *vinfo = NULL;
14092 u32 output_index;
14093
14094 output_index = get_output_device_id(index);
14095 if (!osd_hw.hwc_enable[output_index]) {
14096 if (index >= OSD2)
14097 return;
14098 } else {
14099 if (index > OSD3)
14100 return;
14101 }
14102
14103 osd_hw.buffer_alloc[index] = 1;
14104 if (osd_hw.osd_fps_start[output_index])
14105 osd_hw.osd_fps[output_index]++;
Googler9398cc32022-12-02 17:21:52 +080014106
Googler4f18c0c2022-09-20 17:23:36 +080014107 osd_enable = (plane_map->enable & 1) ? ENABLE : DISABLE;
14108
Googler9398cc32022-12-02 17:21:52 +080014109#ifdef CONFIG_AMLOGIC_VOUT_SERVE
Googler4f18c0c2022-09-20 17:23:36 +080014110 if (output_index == VIU1)
14111 vinfo = get_current_vinfo();
Googler9398cc32022-12-02 17:21:52 +080014112#endif
Googler4f18c0c2022-09-20 17:23:36 +080014113#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
14114 else if (output_index == VIU2)
14115 vinfo = get_current_vinfo2();
14116#endif
Googler9398cc32022-12-02 17:21:52 +080014117 if (!vinfo || !vinfo->name || (!strcmp(vinfo->name, "invalid") ||
14118 !strcmp(vinfo->name, "null")))
Googler4f18c0c2022-09-20 17:23:36 +080014119 return;
Googler9398cc32022-12-02 17:21:52 +080014120
Googler4f18c0c2022-09-20 17:23:36 +080014121 osd_hw.vinfo_width[output_index] = vinfo->width;
14122 osd_hw.vinfo_height[output_index] = vinfo->height;
14123
14124 osd_hw.osd_afbcd[index].enable =
14125 (plane_map->afbc_inter_format & AFBC_EN) >> 31;
14126 if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
Googler9398cc32022-12-02 17:21:52 +080014127 if (plane_map->phy_addr && plane_map->src_w &&
14128 plane_map->src_h && index == OSD1) {
Googler4f18c0c2022-09-20 17:23:36 +080014129 osd_hw.fb_gem[index].canvas_idx =
14130 osd_extra_idx[index][ext_canvas_id[index]];
14131 ext_canvas_id[index] ^= 1;
14132 color = convert_panel_format(plane_map->format);
Googler9398cc32022-12-02 17:21:52 +080014133 if (color)
Googler4f18c0c2022-09-20 17:23:36 +080014134 osd_hw.color_info[index] = color;
Googler9398cc32022-12-02 17:21:52 +080014135 else
Googler4f18c0c2022-09-20 17:23:36 +080014136 osd_log_err("fence color format error %d\n",
Googler9398cc32022-12-02 17:21:52 +080014137 plane_map->format);
Googler4f18c0c2022-09-20 17:23:36 +080014138
14139 freescale_update = osd_direct_render(plane_map);
14140
14141 if (index == OSD1 &&
Googler9398cc32022-12-02 17:21:52 +080014142 osd_hw.osd_afbcd[index].enable == ENABLE)
Googler4f18c0c2022-09-20 17:23:36 +080014143 osd_hw.osd_afbcd[index].phy_addr =
14144 plane_map->phy_addr;
14145 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
14146 osd_hw.reg[DISP_GEOMETRY].update_func(index);
14147 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
Googler9398cc32022-12-02 17:21:52 +080014148 if ((osd_hw.free_scale_enable[index] &&
14149 osd_update_window_axis) ||
14150 freescale_update) {
Googler9726be62022-12-14 05:53:31 +000014151 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +080014152 osd_hw.reg[DISP_FREESCALE_ENABLE]
14153 .update_func(index);
14154 osd_update_window_axis = false;
14155 }
Googler9398cc32022-12-02 17:21:52 +080014156 if (osd_hw.osd_afbcd[index].enable == DISABLE &&
14157 osd_enable != osd_hw.enable[index] &&
14158 !suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +080014159 osd_hw.enable[index] = osd_enable;
Googler9726be62022-12-14 05:53:31 +000014160 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +080014161 osd_hw.reg[OSD_ENABLE]
14162 .update_func(index);
14163 }
14164 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +080014165 osd_mali_afbc_start(output_index);
Googler9726be62022-12-14 05:53:31 +000014166 osd_wait_vsync_hw(index);
Googler9398cc32022-12-02 17:21:52 +080014167 } else if (plane_map->phy_addr && plane_map->src_w &&
14168 plane_map->src_h && index == OSD2) {
Googler4f18c0c2022-09-20 17:23:36 +080014169 color = convert_panel_format(plane_map->format);
14170 if (color) {
14171 osd_hw.color_info[index] = color;
Googler9398cc32022-12-02 17:21:52 +080014172 } else {
Googler4f18c0c2022-09-20 17:23:36 +080014173 osd_log_err("fence color format error %d\n",
Googler9398cc32022-12-02 17:21:52 +080014174 plane_map->format);
14175 }
Googler4f18c0c2022-09-20 17:23:36 +080014176 if (osd_hw.hw_cursor_en)
14177 osd_cursor_move(plane_map);
14178 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
14179 osd_hw.reg[DISP_GEOMETRY].update_func(index);
14180 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
Googler9398cc32022-12-02 17:21:52 +080014181 if (osd_enable != osd_hw.enable[index] &&
14182 !suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +080014183 osd_hw.enable[index] = osd_enable;
Googler9726be62022-12-14 05:53:31 +000014184 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +080014185 osd_hw.reg[OSD_ENABLE]
14186 .update_func(index);
14187 }
14188 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +080014189 osd_mali_afbc_start(output_index);
Googler4f18c0c2022-09-20 17:23:36 +080014190 }
14191 } else {
Googler9398cc32022-12-02 17:21:52 +080014192 if (plane_map->phy_addr && plane_map->src_w &&
14193 plane_map->src_h) {
Googler4f18c0c2022-09-20 17:23:36 +080014194 osd_hw.fb_gem[index].canvas_idx =
14195 osd_extra_idx[index][ext_canvas_id[index]];
14196 ext_canvas_id[index] ^= 1;
Googler9398cc32022-12-02 17:21:52 +080014197
Googler4f18c0c2022-09-20 17:23:36 +080014198 if (osd_hw.osd_afbcd[index].enable)
14199 format = plane_map->format | AFBC_EN;
14200 else
14201 format = plane_map->format;
14202 color = convert_panel_format(format);
14203 if (color) {
14204 osd_hw.color_info[index] = color;
14205 } else {
14206 osd_log_err("fence color format error %d\n",
Googler9398cc32022-12-02 17:21:52 +080014207 plane_map->format);
Googler4f18c0c2022-09-20 17:23:36 +080014208 return;
14209 }
14210 osd_hw.osd_afbcd[index].format =
14211 color->color_index;
14212 freescale_update = osd_direct_render(plane_map);
14213
14214 if (osd_hw.osd_afbcd[index].enable == ENABLE)
14215 osd_hw.osd_afbcd[index].phy_addr =
14216 plane_map->phy_addr;
14217 osd_hw.reg[OSD_COLOR_MODE].update_func(index);
14218 if (!osd_hw.hwc_enable[output_index]) {
14219 osd_hw.reg[DISP_GEOMETRY].update_func(index);
14220 osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
Googler9398cc32022-12-02 17:21:52 +080014221 if ((osd_hw.free_scale_enable[index] &&
14222 osd_update_window_axis) ||
14223 freescale_update) {
Googler9726be62022-12-14 05:53:31 +000014224 if (!osd_hw.osd_display_debug
Googler9398cc32022-12-02 17:21:52 +080014225 [output_index])
14226 osd_hw.reg[DISP_FREESCALE_ENABLE]
14227 .update_func(index);
Googler4f18c0c2022-09-20 17:23:36 +080014228 osd_update_window_axis = false;
14229 }
14230 }
Googler9398cc32022-12-02 17:21:52 +080014231 if (osd_hw.osd_afbcd[index].enable == DISABLE &&
14232 osd_enable != osd_hw.enable[index] &&
14233 !suspend_flag) {
Googler4f18c0c2022-09-20 17:23:36 +080014234 osd_hw.enable[index] = osd_enable;
Googler9726be62022-12-14 05:53:31 +000014235 if (!osd_hw.osd_display_debug[output_index])
Googler4f18c0c2022-09-20 17:23:36 +080014236 osd_hw.reg[OSD_ENABLE]
14237 .update_func(index);
14238 }
14239 if (osd_hw.hw_rdma_en)
Googler9398cc32022-12-02 17:21:52 +080014240 osd_mali_afbc_start(output_index);
Googler9726be62022-12-14 05:53:31 +000014241 osd_wait_vsync_hw(index);
Googler4f18c0c2022-09-20 17:23:36 +080014242 }
14243 }
14244}