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