1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * linux/include/video/mmp_disp.h
4*4882a593Smuzhiyun * Header file for Marvell MMP Display Controller
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2012 Marvell Technology Group Ltd.
7*4882a593Smuzhiyun * Authors: Zhou Zhu <zzhu3@marvell.com>
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #ifndef _MMP_DISP_H_
11*4882a593Smuzhiyun #define _MMP_DISP_H_
12*4882a593Smuzhiyun #include <linux/kthread.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun enum {
15*4882a593Smuzhiyun PIXFMT_UYVY = 0,
16*4882a593Smuzhiyun PIXFMT_VYUY,
17*4882a593Smuzhiyun PIXFMT_YUYV,
18*4882a593Smuzhiyun PIXFMT_YUV422P,
19*4882a593Smuzhiyun PIXFMT_YVU422P,
20*4882a593Smuzhiyun PIXFMT_YUV420P,
21*4882a593Smuzhiyun PIXFMT_YVU420P,
22*4882a593Smuzhiyun PIXFMT_RGB565 = 0x100,
23*4882a593Smuzhiyun PIXFMT_BGR565,
24*4882a593Smuzhiyun PIXFMT_RGB1555,
25*4882a593Smuzhiyun PIXFMT_BGR1555,
26*4882a593Smuzhiyun PIXFMT_RGB888PACK,
27*4882a593Smuzhiyun PIXFMT_BGR888PACK,
28*4882a593Smuzhiyun PIXFMT_RGB888UNPACK,
29*4882a593Smuzhiyun PIXFMT_BGR888UNPACK,
30*4882a593Smuzhiyun PIXFMT_RGBA888,
31*4882a593Smuzhiyun PIXFMT_BGRA888,
32*4882a593Smuzhiyun PIXFMT_RGB666, /* for output usage */
33*4882a593Smuzhiyun PIXFMT_PSEUDOCOLOR = 0x200,
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun
pixfmt_to_stride(int pix_fmt)36*4882a593Smuzhiyun static inline int pixfmt_to_stride(int pix_fmt)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun switch (pix_fmt) {
39*4882a593Smuzhiyun case PIXFMT_RGB565:
40*4882a593Smuzhiyun case PIXFMT_BGR565:
41*4882a593Smuzhiyun case PIXFMT_RGB1555:
42*4882a593Smuzhiyun case PIXFMT_BGR1555:
43*4882a593Smuzhiyun case PIXFMT_UYVY:
44*4882a593Smuzhiyun case PIXFMT_VYUY:
45*4882a593Smuzhiyun case PIXFMT_YUYV:
46*4882a593Smuzhiyun return 2;
47*4882a593Smuzhiyun case PIXFMT_RGB888UNPACK:
48*4882a593Smuzhiyun case PIXFMT_BGR888UNPACK:
49*4882a593Smuzhiyun case PIXFMT_RGBA888:
50*4882a593Smuzhiyun case PIXFMT_BGRA888:
51*4882a593Smuzhiyun return 4;
52*4882a593Smuzhiyun case PIXFMT_RGB888PACK:
53*4882a593Smuzhiyun case PIXFMT_BGR888PACK:
54*4882a593Smuzhiyun return 3;
55*4882a593Smuzhiyun case PIXFMT_YUV422P:
56*4882a593Smuzhiyun case PIXFMT_YVU422P:
57*4882a593Smuzhiyun case PIXFMT_YUV420P:
58*4882a593Smuzhiyun case PIXFMT_YVU420P:
59*4882a593Smuzhiyun case PIXFMT_PSEUDOCOLOR:
60*4882a593Smuzhiyun return 1;
61*4882a593Smuzhiyun default:
62*4882a593Smuzhiyun return 0;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /* parameters used by path/overlay */
67*4882a593Smuzhiyun /* overlay related para: win/addr */
68*4882a593Smuzhiyun struct mmp_win {
69*4882a593Smuzhiyun /* position/size of window */
70*4882a593Smuzhiyun u16 xsrc;
71*4882a593Smuzhiyun u16 ysrc;
72*4882a593Smuzhiyun u16 xdst;
73*4882a593Smuzhiyun u16 ydst;
74*4882a593Smuzhiyun u16 xpos;
75*4882a593Smuzhiyun u16 ypos;
76*4882a593Smuzhiyun u16 left_crop;
77*4882a593Smuzhiyun u16 right_crop;
78*4882a593Smuzhiyun u16 up_crop;
79*4882a593Smuzhiyun u16 bottom_crop;
80*4882a593Smuzhiyun int pix_fmt;
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun * pitch[0]: graphics/video layer line length or y pitch
83*4882a593Smuzhiyun * pitch[1]/pitch[2]: video u/v pitch if non-zero
84*4882a593Smuzhiyun */
85*4882a593Smuzhiyun u32 pitch[3];
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun struct mmp_addr {
89*4882a593Smuzhiyun /* phys address */
90*4882a593Smuzhiyun u32 phys[6];
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /* path related para: mode */
94*4882a593Smuzhiyun struct mmp_mode {
95*4882a593Smuzhiyun const char *name;
96*4882a593Smuzhiyun u32 refresh;
97*4882a593Smuzhiyun u32 xres;
98*4882a593Smuzhiyun u32 yres;
99*4882a593Smuzhiyun u32 left_margin;
100*4882a593Smuzhiyun u32 right_margin;
101*4882a593Smuzhiyun u32 upper_margin;
102*4882a593Smuzhiyun u32 lower_margin;
103*4882a593Smuzhiyun u32 hsync_len;
104*4882a593Smuzhiyun u32 vsync_len;
105*4882a593Smuzhiyun u32 hsync_invert;
106*4882a593Smuzhiyun u32 vsync_invert;
107*4882a593Smuzhiyun u32 invert_pixclock;
108*4882a593Smuzhiyun u32 pixclock_freq;
109*4882a593Smuzhiyun int pix_fmt_out;
110*4882a593Smuzhiyun };
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun /* main structures */
113*4882a593Smuzhiyun struct mmp_path;
114*4882a593Smuzhiyun struct mmp_overlay;
115*4882a593Smuzhiyun struct mmp_panel;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /* status types */
118*4882a593Smuzhiyun enum {
119*4882a593Smuzhiyun MMP_OFF = 0,
120*4882a593Smuzhiyun MMP_ON,
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun
stat_name(int stat)123*4882a593Smuzhiyun static inline const char *stat_name(int stat)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun switch (stat) {
126*4882a593Smuzhiyun case MMP_OFF:
127*4882a593Smuzhiyun return "OFF";
128*4882a593Smuzhiyun case MMP_ON:
129*4882a593Smuzhiyun return "ON";
130*4882a593Smuzhiyun default:
131*4882a593Smuzhiyun return "UNKNOWNSTAT";
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun struct mmp_overlay_ops {
136*4882a593Smuzhiyun /* should be provided by driver */
137*4882a593Smuzhiyun void (*set_fetch)(struct mmp_overlay *overlay, int fetch_id);
138*4882a593Smuzhiyun void (*set_onoff)(struct mmp_overlay *overlay, int status);
139*4882a593Smuzhiyun void (*set_win)(struct mmp_overlay *overlay, struct mmp_win *win);
140*4882a593Smuzhiyun int (*set_addr)(struct mmp_overlay *overlay, struct mmp_addr *addr);
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun /* overlay describes a z-order indexed slot in each path. */
144*4882a593Smuzhiyun struct mmp_overlay {
145*4882a593Smuzhiyun int id;
146*4882a593Smuzhiyun const char *name;
147*4882a593Smuzhiyun struct mmp_path *path;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* overlay info: private data */
150*4882a593Smuzhiyun int dmafetch_id;
151*4882a593Smuzhiyun struct mmp_addr addr;
152*4882a593Smuzhiyun struct mmp_win win;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /* state */
155*4882a593Smuzhiyun int open_count;
156*4882a593Smuzhiyun int status;
157*4882a593Smuzhiyun struct mutex access_ok;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun struct mmp_overlay_ops *ops;
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun /* panel type */
163*4882a593Smuzhiyun enum {
164*4882a593Smuzhiyun PANELTYPE_ACTIVE = 0,
165*4882a593Smuzhiyun PANELTYPE_SMART,
166*4882a593Smuzhiyun PANELTYPE_TV,
167*4882a593Smuzhiyun PANELTYPE_DSI_CMD,
168*4882a593Smuzhiyun PANELTYPE_DSI_VIDEO,
169*4882a593Smuzhiyun };
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun struct mmp_panel {
172*4882a593Smuzhiyun /* use node to register to list */
173*4882a593Smuzhiyun struct list_head node;
174*4882a593Smuzhiyun const char *name;
175*4882a593Smuzhiyun /* path name used to connect to proper path configed */
176*4882a593Smuzhiyun const char *plat_path_name;
177*4882a593Smuzhiyun struct device *dev;
178*4882a593Smuzhiyun int panel_type;
179*4882a593Smuzhiyun void *plat_data;
180*4882a593Smuzhiyun int (*get_modelist)(struct mmp_panel *panel,
181*4882a593Smuzhiyun struct mmp_mode **modelist);
182*4882a593Smuzhiyun void (*set_mode)(struct mmp_panel *panel,
183*4882a593Smuzhiyun struct mmp_mode *mode);
184*4882a593Smuzhiyun void (*set_onoff)(struct mmp_panel *panel,
185*4882a593Smuzhiyun int status);
186*4882a593Smuzhiyun };
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun struct mmp_path_ops {
189*4882a593Smuzhiyun int (*check_status)(struct mmp_path *path);
190*4882a593Smuzhiyun struct mmp_overlay *(*get_overlay)(struct mmp_path *path,
191*4882a593Smuzhiyun int overlay_id);
192*4882a593Smuzhiyun int (*get_modelist)(struct mmp_path *path,
193*4882a593Smuzhiyun struct mmp_mode **modelist);
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun /* follow ops should be provided by driver */
196*4882a593Smuzhiyun void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
197*4882a593Smuzhiyun void (*set_onoff)(struct mmp_path *path, int status);
198*4882a593Smuzhiyun /* todo: add query */
199*4882a593Smuzhiyun };
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /* path output types */
202*4882a593Smuzhiyun enum {
203*4882a593Smuzhiyun PATH_OUT_PARALLEL,
204*4882a593Smuzhiyun PATH_OUT_DSI,
205*4882a593Smuzhiyun PATH_OUT_HDMI,
206*4882a593Smuzhiyun };
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* path is main part of mmp-disp */
209*4882a593Smuzhiyun struct mmp_path {
210*4882a593Smuzhiyun /* use node to register to list */
211*4882a593Smuzhiyun struct list_head node;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun /* init data */
214*4882a593Smuzhiyun struct device *dev;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun int id;
217*4882a593Smuzhiyun const char *name;
218*4882a593Smuzhiyun int output_type;
219*4882a593Smuzhiyun struct mmp_panel *panel;
220*4882a593Smuzhiyun void *plat_data;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* dynamic use */
223*4882a593Smuzhiyun struct mmp_mode mode;
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /* state */
226*4882a593Smuzhiyun int open_count;
227*4882a593Smuzhiyun int status;
228*4882a593Smuzhiyun struct mutex access_ok;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun struct mmp_path_ops ops;
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /* layers */
233*4882a593Smuzhiyun int overlay_num;
234*4882a593Smuzhiyun struct mmp_overlay overlays[];
235*4882a593Smuzhiyun };
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun extern struct mmp_path *mmp_get_path(const char *name);
mmp_path_set_mode(struct mmp_path * path,struct mmp_mode * mode)238*4882a593Smuzhiyun static inline void mmp_path_set_mode(struct mmp_path *path,
239*4882a593Smuzhiyun struct mmp_mode *mode)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun if (path)
242*4882a593Smuzhiyun path->ops.set_mode(path, mode);
243*4882a593Smuzhiyun }
mmp_path_set_onoff(struct mmp_path * path,int status)244*4882a593Smuzhiyun static inline void mmp_path_set_onoff(struct mmp_path *path, int status)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun if (path)
247*4882a593Smuzhiyun path->ops.set_onoff(path, status);
248*4882a593Smuzhiyun }
mmp_path_get_modelist(struct mmp_path * path,struct mmp_mode ** modelist)249*4882a593Smuzhiyun static inline int mmp_path_get_modelist(struct mmp_path *path,
250*4882a593Smuzhiyun struct mmp_mode **modelist)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun if (path)
253*4882a593Smuzhiyun return path->ops.get_modelist(path, modelist);
254*4882a593Smuzhiyun return 0;
255*4882a593Smuzhiyun }
mmp_path_get_overlay(struct mmp_path * path,int overlay_id)256*4882a593Smuzhiyun static inline struct mmp_overlay *mmp_path_get_overlay(
257*4882a593Smuzhiyun struct mmp_path *path, int overlay_id)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun if (path)
260*4882a593Smuzhiyun return path->ops.get_overlay(path, overlay_id);
261*4882a593Smuzhiyun return NULL;
262*4882a593Smuzhiyun }
mmp_overlay_set_fetch(struct mmp_overlay * overlay,int fetch_id)263*4882a593Smuzhiyun static inline void mmp_overlay_set_fetch(struct mmp_overlay *overlay,
264*4882a593Smuzhiyun int fetch_id)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun if (overlay)
267*4882a593Smuzhiyun overlay->ops->set_fetch(overlay, fetch_id);
268*4882a593Smuzhiyun }
mmp_overlay_set_onoff(struct mmp_overlay * overlay,int status)269*4882a593Smuzhiyun static inline void mmp_overlay_set_onoff(struct mmp_overlay *overlay,
270*4882a593Smuzhiyun int status)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun if (overlay)
273*4882a593Smuzhiyun overlay->ops->set_onoff(overlay, status);
274*4882a593Smuzhiyun }
mmp_overlay_set_win(struct mmp_overlay * overlay,struct mmp_win * win)275*4882a593Smuzhiyun static inline void mmp_overlay_set_win(struct mmp_overlay *overlay,
276*4882a593Smuzhiyun struct mmp_win *win)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun if (overlay)
279*4882a593Smuzhiyun overlay->ops->set_win(overlay, win);
280*4882a593Smuzhiyun }
mmp_overlay_set_addr(struct mmp_overlay * overlay,struct mmp_addr * addr)281*4882a593Smuzhiyun static inline int mmp_overlay_set_addr(struct mmp_overlay *overlay,
282*4882a593Smuzhiyun struct mmp_addr *addr)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun if (overlay)
285*4882a593Smuzhiyun return overlay->ops->set_addr(overlay, addr);
286*4882a593Smuzhiyun return 0;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun /*
290*4882a593Smuzhiyun * driver data is set from each detailed ctrl driver for path usage
291*4882a593Smuzhiyun * it defined a common interface that plat driver need to implement
292*4882a593Smuzhiyun */
293*4882a593Smuzhiyun struct mmp_path_info {
294*4882a593Smuzhiyun /* driver data, set when registed*/
295*4882a593Smuzhiyun const char *name;
296*4882a593Smuzhiyun struct device *dev;
297*4882a593Smuzhiyun int id;
298*4882a593Smuzhiyun int output_type;
299*4882a593Smuzhiyun int overlay_num;
300*4882a593Smuzhiyun void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
301*4882a593Smuzhiyun void (*set_onoff)(struct mmp_path *path, int status);
302*4882a593Smuzhiyun struct mmp_overlay_ops *overlay_ops;
303*4882a593Smuzhiyun void *plat_data;
304*4882a593Smuzhiyun };
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun extern struct mmp_path *mmp_register_path(
307*4882a593Smuzhiyun struct mmp_path_info *info);
308*4882a593Smuzhiyun extern void mmp_unregister_path(struct mmp_path *path);
309*4882a593Smuzhiyun extern void mmp_register_panel(struct mmp_panel *panel);
310*4882a593Smuzhiyun extern void mmp_unregister_panel(struct mmp_panel *panel);
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /* defintions for platform data */
313*4882a593Smuzhiyun /* interface for buffer driver */
314*4882a593Smuzhiyun struct mmp_buffer_driver_mach_info {
315*4882a593Smuzhiyun const char *name;
316*4882a593Smuzhiyun const char *path_name;
317*4882a593Smuzhiyun int overlay_id;
318*4882a593Smuzhiyun int dmafetch_id;
319*4882a593Smuzhiyun int default_pixfmt;
320*4882a593Smuzhiyun };
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun /* interface for controllers driver */
323*4882a593Smuzhiyun struct mmp_mach_path_config {
324*4882a593Smuzhiyun const char *name;
325*4882a593Smuzhiyun int overlay_num;
326*4882a593Smuzhiyun int output_type;
327*4882a593Smuzhiyun u32 path_config;
328*4882a593Smuzhiyun u32 link_config;
329*4882a593Smuzhiyun u32 dsi_rbswap;
330*4882a593Smuzhiyun };
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun struct mmp_mach_plat_info {
333*4882a593Smuzhiyun const char *name;
334*4882a593Smuzhiyun const char *clk_name;
335*4882a593Smuzhiyun int path_num;
336*4882a593Smuzhiyun struct mmp_mach_path_config *paths;
337*4882a593Smuzhiyun };
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /* interface for panel drivers */
340*4882a593Smuzhiyun struct mmp_mach_panel_info {
341*4882a593Smuzhiyun const char *name;
342*4882a593Smuzhiyun void (*plat_set_onoff)(int status);
343*4882a593Smuzhiyun const char *plat_path_name;
344*4882a593Smuzhiyun };
345*4882a593Smuzhiyun #endif /* _MMP_DISP_H_ */
346