xref: /openbmc/linux/include/video/mmp_disp.h (revision e3487252)
11ccea77eSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
259393bb9SZhou Zhu /*
359393bb9SZhou Zhu  * linux/include/video/mmp_disp.h
459393bb9SZhou Zhu  * Header file for Marvell MMP Display Controller
559393bb9SZhou Zhu  *
659393bb9SZhou Zhu  * Copyright (C) 2012 Marvell Technology Group Ltd.
759393bb9SZhou Zhu  * Authors: Zhou Zhu <zzhu3@marvell.com>
859393bb9SZhou Zhu  */
959393bb9SZhou Zhu 
1059393bb9SZhou Zhu #ifndef _MMP_DISP_H_
1159393bb9SZhou Zhu #define _MMP_DISP_H_
1259393bb9SZhou Zhu #include <linux/kthread.h>
1359393bb9SZhou Zhu 
1459393bb9SZhou Zhu enum {
1559393bb9SZhou Zhu 	PIXFMT_UYVY = 0,
1659393bb9SZhou Zhu 	PIXFMT_VYUY,
1759393bb9SZhou Zhu 	PIXFMT_YUYV,
1859393bb9SZhou Zhu 	PIXFMT_YUV422P,
1959393bb9SZhou Zhu 	PIXFMT_YVU422P,
2059393bb9SZhou Zhu 	PIXFMT_YUV420P,
2159393bb9SZhou Zhu 	PIXFMT_YVU420P,
2259393bb9SZhou Zhu 	PIXFMT_RGB565 = 0x100,
2359393bb9SZhou Zhu 	PIXFMT_BGR565,
2459393bb9SZhou Zhu 	PIXFMT_RGB1555,
2559393bb9SZhou Zhu 	PIXFMT_BGR1555,
2659393bb9SZhou Zhu 	PIXFMT_RGB888PACK,
2759393bb9SZhou Zhu 	PIXFMT_BGR888PACK,
2859393bb9SZhou Zhu 	PIXFMT_RGB888UNPACK,
2959393bb9SZhou Zhu 	PIXFMT_BGR888UNPACK,
3059393bb9SZhou Zhu 	PIXFMT_RGBA888,
3159393bb9SZhou Zhu 	PIXFMT_BGRA888,
3259393bb9SZhou Zhu 	PIXFMT_RGB666, /* for output usage */
3359393bb9SZhou Zhu 	PIXFMT_PSEUDOCOLOR = 0x200,
3459393bb9SZhou Zhu };
3559393bb9SZhou Zhu 
pixfmt_to_stride(int pix_fmt)3659393bb9SZhou Zhu static inline int pixfmt_to_stride(int pix_fmt)
3759393bb9SZhou Zhu {
3859393bb9SZhou Zhu 	switch (pix_fmt) {
3959393bb9SZhou Zhu 	case PIXFMT_RGB565:
4059393bb9SZhou Zhu 	case PIXFMT_BGR565:
4159393bb9SZhou Zhu 	case PIXFMT_RGB1555:
4259393bb9SZhou Zhu 	case PIXFMT_BGR1555:
4359393bb9SZhou Zhu 	case PIXFMT_UYVY:
4459393bb9SZhou Zhu 	case PIXFMT_VYUY:
4559393bb9SZhou Zhu 	case PIXFMT_YUYV:
4659393bb9SZhou Zhu 		return 2;
4759393bb9SZhou Zhu 	case PIXFMT_RGB888UNPACK:
4859393bb9SZhou Zhu 	case PIXFMT_BGR888UNPACK:
4959393bb9SZhou Zhu 	case PIXFMT_RGBA888:
5059393bb9SZhou Zhu 	case PIXFMT_BGRA888:
5159393bb9SZhou Zhu 		return 4;
5259393bb9SZhou Zhu 	case PIXFMT_RGB888PACK:
5359393bb9SZhou Zhu 	case PIXFMT_BGR888PACK:
5459393bb9SZhou Zhu 		return 3;
5559393bb9SZhou Zhu 	case PIXFMT_YUV422P:
5659393bb9SZhou Zhu 	case PIXFMT_YVU422P:
5759393bb9SZhou Zhu 	case PIXFMT_YUV420P:
5859393bb9SZhou Zhu 	case PIXFMT_YVU420P:
5959393bb9SZhou Zhu 	case PIXFMT_PSEUDOCOLOR:
6059393bb9SZhou Zhu 		return 1;
6159393bb9SZhou Zhu 	default:
6259393bb9SZhou Zhu 		return 0;
6359393bb9SZhou Zhu 	}
6459393bb9SZhou Zhu }
6559393bb9SZhou Zhu 
6659393bb9SZhou Zhu /* parameters used by path/overlay */
6759393bb9SZhou Zhu /* overlay related para: win/addr */
6859393bb9SZhou Zhu struct mmp_win {
6959393bb9SZhou Zhu 	/* position/size of window */
7059393bb9SZhou Zhu 	u16	xsrc;
7159393bb9SZhou Zhu 	u16	ysrc;
7259393bb9SZhou Zhu 	u16	xdst;
7359393bb9SZhou Zhu 	u16	ydst;
7459393bb9SZhou Zhu 	u16	xpos;
7559393bb9SZhou Zhu 	u16	ypos;
7659393bb9SZhou Zhu 	u16	left_crop;
7759393bb9SZhou Zhu 	u16	right_crop;
7859393bb9SZhou Zhu 	u16	up_crop;
7959393bb9SZhou Zhu 	u16	bottom_crop;
8059393bb9SZhou Zhu 	int	pix_fmt;
8124586d83SJing Xiang 	/*
8224586d83SJing Xiang 	 * pitch[0]: graphics/video layer line length or y pitch
8324586d83SJing Xiang 	 * pitch[1]/pitch[2]: video u/v pitch if non-zero
8424586d83SJing Xiang 	 */
8524586d83SJing Xiang 	u32	pitch[3];
8659393bb9SZhou Zhu };
8759393bb9SZhou Zhu 
8859393bb9SZhou Zhu struct mmp_addr {
8959393bb9SZhou Zhu 	/* phys address */
9059393bb9SZhou Zhu 	u32	phys[6];
9159393bb9SZhou Zhu };
9259393bb9SZhou Zhu 
9359393bb9SZhou Zhu /* path related para: mode */
9459393bb9SZhou Zhu struct mmp_mode {
9559393bb9SZhou Zhu 	const char *name;
9659393bb9SZhou Zhu 	u32 refresh;
9759393bb9SZhou Zhu 	u32 xres;
9859393bb9SZhou Zhu 	u32 yres;
9959393bb9SZhou Zhu 	u32 left_margin;
10059393bb9SZhou Zhu 	u32 right_margin;
10159393bb9SZhou Zhu 	u32 upper_margin;
10259393bb9SZhou Zhu 	u32 lower_margin;
10359393bb9SZhou Zhu 	u32 hsync_len;
10459393bb9SZhou Zhu 	u32 vsync_len;
10559393bb9SZhou Zhu 	u32 hsync_invert;
10659393bb9SZhou Zhu 	u32 vsync_invert;
10759393bb9SZhou Zhu 	u32 invert_pixclock;
10859393bb9SZhou Zhu 	u32 pixclock_freq;
10959393bb9SZhou Zhu 	int pix_fmt_out;
11059393bb9SZhou Zhu };
11159393bb9SZhou Zhu 
11259393bb9SZhou Zhu /* main structures */
11359393bb9SZhou Zhu struct mmp_path;
11459393bb9SZhou Zhu struct mmp_overlay;
11559393bb9SZhou Zhu struct mmp_panel;
11659393bb9SZhou Zhu 
11759393bb9SZhou Zhu /* status types */
11859393bb9SZhou Zhu enum {
11959393bb9SZhou Zhu 	MMP_OFF = 0,
12059393bb9SZhou Zhu 	MMP_ON,
12159393bb9SZhou Zhu };
12259393bb9SZhou Zhu 
stat_name(int stat)12359393bb9SZhou Zhu static inline const char *stat_name(int stat)
12459393bb9SZhou Zhu {
12559393bb9SZhou Zhu 	switch (stat) {
12659393bb9SZhou Zhu 	case MMP_OFF:
12759393bb9SZhou Zhu 		return "OFF";
12859393bb9SZhou Zhu 	case MMP_ON:
12959393bb9SZhou Zhu 		return "ON";
13059393bb9SZhou Zhu 	default:
13159393bb9SZhou Zhu 		return "UNKNOWNSTAT";
13259393bb9SZhou Zhu 	}
13359393bb9SZhou Zhu }
13459393bb9SZhou Zhu 
13559393bb9SZhou Zhu struct mmp_overlay_ops {
13659393bb9SZhou Zhu 	/* should be provided by driver */
13759393bb9SZhou Zhu 	void (*set_fetch)(struct mmp_overlay *overlay, int fetch_id);
13859393bb9SZhou Zhu 	void (*set_onoff)(struct mmp_overlay *overlay, int status);
13959393bb9SZhou Zhu 	void (*set_win)(struct mmp_overlay *overlay, struct mmp_win *win);
14059393bb9SZhou Zhu 	int (*set_addr)(struct mmp_overlay *overlay, struct mmp_addr *addr);
14159393bb9SZhou Zhu };
14259393bb9SZhou Zhu 
14359393bb9SZhou Zhu /* overlay describes a z-order indexed slot in each path. */
14459393bb9SZhou Zhu struct mmp_overlay {
14559393bb9SZhou Zhu 	int id;
14659393bb9SZhou Zhu 	const char *name;
14759393bb9SZhou Zhu 	struct mmp_path *path;
14859393bb9SZhou Zhu 
14959393bb9SZhou Zhu 	/* overlay info: private data */
15059393bb9SZhou Zhu 	int dmafetch_id;
15159393bb9SZhou Zhu 	struct mmp_addr addr;
15259393bb9SZhou Zhu 	struct mmp_win win;
15359393bb9SZhou Zhu 
15459393bb9SZhou Zhu 	/* state */
15559393bb9SZhou Zhu 	int open_count;
15659393bb9SZhou Zhu 	int status;
15759393bb9SZhou Zhu 	struct mutex access_ok;
15859393bb9SZhou Zhu 
15959393bb9SZhou Zhu 	struct mmp_overlay_ops *ops;
16059393bb9SZhou Zhu };
16159393bb9SZhou Zhu 
16259393bb9SZhou Zhu /* panel type */
16359393bb9SZhou Zhu enum {
16459393bb9SZhou Zhu 	PANELTYPE_ACTIVE = 0,
16559393bb9SZhou Zhu 	PANELTYPE_SMART,
16659393bb9SZhou Zhu 	PANELTYPE_TV,
16759393bb9SZhou Zhu 	PANELTYPE_DSI_CMD,
16859393bb9SZhou Zhu 	PANELTYPE_DSI_VIDEO,
16959393bb9SZhou Zhu };
17059393bb9SZhou Zhu 
17159393bb9SZhou Zhu struct mmp_panel {
17259393bb9SZhou Zhu 	/* use node to register to list */
17359393bb9SZhou Zhu 	struct list_head node;
17459393bb9SZhou Zhu 	const char *name;
17559393bb9SZhou Zhu 	/* path name used to connect to proper path configed */
17659393bb9SZhou Zhu 	const char *plat_path_name;
17759393bb9SZhou Zhu 	struct device *dev;
17859393bb9SZhou Zhu 	int panel_type;
17959393bb9SZhou Zhu 	void *plat_data;
18059393bb9SZhou Zhu 	int (*get_modelist)(struct mmp_panel *panel,
18159393bb9SZhou Zhu 			struct mmp_mode **modelist);
18259393bb9SZhou Zhu 	void (*set_mode)(struct mmp_panel *panel,
18359393bb9SZhou Zhu 			struct mmp_mode *mode);
18459393bb9SZhou Zhu 	void (*set_onoff)(struct mmp_panel *panel,
18559393bb9SZhou Zhu 			int status);
18659393bb9SZhou Zhu };
18759393bb9SZhou Zhu 
18859393bb9SZhou Zhu struct mmp_path_ops {
18959393bb9SZhou Zhu 	int (*check_status)(struct mmp_path *path);
19059393bb9SZhou Zhu 	struct mmp_overlay *(*get_overlay)(struct mmp_path *path,
19159393bb9SZhou Zhu 			int overlay_id);
19259393bb9SZhou Zhu 	int (*get_modelist)(struct mmp_path *path,
19359393bb9SZhou Zhu 			struct mmp_mode **modelist);
19459393bb9SZhou Zhu 
19559393bb9SZhou Zhu 	/* follow ops should be provided by driver */
19659393bb9SZhou Zhu 	void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
19759393bb9SZhou Zhu 	void (*set_onoff)(struct mmp_path *path, int status);
19859393bb9SZhou Zhu 	/* todo: add query */
19959393bb9SZhou Zhu };
20059393bb9SZhou Zhu 
20159393bb9SZhou Zhu /* path output types */
20259393bb9SZhou Zhu enum {
20359393bb9SZhou Zhu 	PATH_OUT_PARALLEL,
20459393bb9SZhou Zhu 	PATH_OUT_DSI,
20559393bb9SZhou Zhu 	PATH_OUT_HDMI,
20659393bb9SZhou Zhu };
20759393bb9SZhou Zhu 
20859393bb9SZhou Zhu /* path is main part of mmp-disp */
20959393bb9SZhou Zhu struct mmp_path {
21059393bb9SZhou Zhu 	/* use node to register to list */
21159393bb9SZhou Zhu 	struct list_head node;
21259393bb9SZhou Zhu 
21359393bb9SZhou Zhu 	/* init data */
21459393bb9SZhou Zhu 	struct device *dev;
21559393bb9SZhou Zhu 
21659393bb9SZhou Zhu 	int id;
21759393bb9SZhou Zhu 	const char *name;
21859393bb9SZhou Zhu 	int output_type;
21959393bb9SZhou Zhu 	struct mmp_panel *panel;
22059393bb9SZhou Zhu 	void *plat_data;
22159393bb9SZhou Zhu 
22259393bb9SZhou Zhu 	/* dynamic use */
22359393bb9SZhou Zhu 	struct mmp_mode mode;
22459393bb9SZhou Zhu 
22559393bb9SZhou Zhu 	/* state */
22659393bb9SZhou Zhu 	int open_count;
22759393bb9SZhou Zhu 	int status;
22859393bb9SZhou Zhu 	struct mutex access_ok;
22959393bb9SZhou Zhu 
23059393bb9SZhou Zhu 	struct mmp_path_ops ops;
23159393bb9SZhou Zhu 
23259393bb9SZhou Zhu 	/* layers */
23359393bb9SZhou Zhu 	int overlay_num;
234*e3487252SKees Cook 	struct mmp_overlay overlays[] __counted_by(overlay_num);
23559393bb9SZhou Zhu };
23659393bb9SZhou Zhu 
23759393bb9SZhou Zhu extern struct mmp_path *mmp_get_path(const char *name);
mmp_path_set_mode(struct mmp_path * path,struct mmp_mode * mode)23859393bb9SZhou Zhu static inline void mmp_path_set_mode(struct mmp_path *path,
23959393bb9SZhou Zhu 		struct mmp_mode *mode)
24059393bb9SZhou Zhu {
24159393bb9SZhou Zhu 	if (path)
24259393bb9SZhou Zhu 		path->ops.set_mode(path, mode);
24359393bb9SZhou Zhu }
mmp_path_set_onoff(struct mmp_path * path,int status)24459393bb9SZhou Zhu static inline void mmp_path_set_onoff(struct mmp_path *path, int status)
24559393bb9SZhou Zhu {
24659393bb9SZhou Zhu 	if (path)
24759393bb9SZhou Zhu 		path->ops.set_onoff(path, status);
24859393bb9SZhou Zhu }
mmp_path_get_modelist(struct mmp_path * path,struct mmp_mode ** modelist)24959393bb9SZhou Zhu static inline int mmp_path_get_modelist(struct mmp_path *path,
25059393bb9SZhou Zhu 		struct mmp_mode **modelist)
25159393bb9SZhou Zhu {
25259393bb9SZhou Zhu 	if (path)
25359393bb9SZhou Zhu 		return path->ops.get_modelist(path, modelist);
25459393bb9SZhou Zhu 	return 0;
25559393bb9SZhou Zhu }
mmp_path_get_overlay(struct mmp_path * path,int overlay_id)25659393bb9SZhou Zhu static inline struct mmp_overlay *mmp_path_get_overlay(
25759393bb9SZhou Zhu 		struct mmp_path *path, int overlay_id)
25859393bb9SZhou Zhu {
25959393bb9SZhou Zhu 	if (path)
26059393bb9SZhou Zhu 		return path->ops.get_overlay(path, overlay_id);
26159393bb9SZhou Zhu 	return NULL;
26259393bb9SZhou Zhu }
mmp_overlay_set_fetch(struct mmp_overlay * overlay,int fetch_id)26359393bb9SZhou Zhu static inline void mmp_overlay_set_fetch(struct mmp_overlay *overlay,
26459393bb9SZhou Zhu 		int fetch_id)
26559393bb9SZhou Zhu {
26659393bb9SZhou Zhu 	if (overlay)
26759393bb9SZhou Zhu 		overlay->ops->set_fetch(overlay, fetch_id);
26859393bb9SZhou Zhu }
mmp_overlay_set_onoff(struct mmp_overlay * overlay,int status)26959393bb9SZhou Zhu static inline void mmp_overlay_set_onoff(struct mmp_overlay *overlay,
27059393bb9SZhou Zhu 		int status)
27159393bb9SZhou Zhu {
27259393bb9SZhou Zhu 	if (overlay)
27359393bb9SZhou Zhu 		overlay->ops->set_onoff(overlay, status);
27459393bb9SZhou Zhu }
mmp_overlay_set_win(struct mmp_overlay * overlay,struct mmp_win * win)27559393bb9SZhou Zhu static inline void mmp_overlay_set_win(struct mmp_overlay *overlay,
27659393bb9SZhou Zhu 		struct mmp_win *win)
27759393bb9SZhou Zhu {
27859393bb9SZhou Zhu 	if (overlay)
27959393bb9SZhou Zhu 		overlay->ops->set_win(overlay, win);
28059393bb9SZhou Zhu }
mmp_overlay_set_addr(struct mmp_overlay * overlay,struct mmp_addr * addr)28159393bb9SZhou Zhu static inline int mmp_overlay_set_addr(struct mmp_overlay *overlay,
28259393bb9SZhou Zhu 		struct mmp_addr *addr)
28359393bb9SZhou Zhu {
28459393bb9SZhou Zhu 	if (overlay)
28559393bb9SZhou Zhu 		return overlay->ops->set_addr(overlay, addr);
28659393bb9SZhou Zhu 	return 0;
28759393bb9SZhou Zhu }
28859393bb9SZhou Zhu 
28959393bb9SZhou Zhu /*
29059393bb9SZhou Zhu  * driver data is set from each detailed ctrl driver for path usage
29159393bb9SZhou Zhu  * it defined a common interface that plat driver need to implement
29259393bb9SZhou Zhu  */
29359393bb9SZhou Zhu struct mmp_path_info {
29459393bb9SZhou Zhu 	/* driver data, set when registed*/
29559393bb9SZhou Zhu 	const char *name;
29659393bb9SZhou Zhu 	struct device *dev;
29759393bb9SZhou Zhu 	int id;
29859393bb9SZhou Zhu 	int output_type;
29959393bb9SZhou Zhu 	int overlay_num;
30059393bb9SZhou Zhu 	void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode);
30159393bb9SZhou Zhu 	void (*set_onoff)(struct mmp_path *path, int status);
30259393bb9SZhou Zhu 	struct mmp_overlay_ops *overlay_ops;
30359393bb9SZhou Zhu 	void *plat_data;
30459393bb9SZhou Zhu };
30559393bb9SZhou Zhu 
30659393bb9SZhou Zhu extern struct mmp_path *mmp_register_path(
30759393bb9SZhou Zhu 		struct mmp_path_info *info);
30859393bb9SZhou Zhu extern void mmp_unregister_path(struct mmp_path *path);
30959393bb9SZhou Zhu extern void mmp_register_panel(struct mmp_panel *panel);
31059393bb9SZhou Zhu extern void mmp_unregister_panel(struct mmp_panel *panel);
31159393bb9SZhou Zhu 
31259393bb9SZhou Zhu /* defintions for platform data */
31359393bb9SZhou Zhu /* interface for buffer driver */
31459393bb9SZhou Zhu struct mmp_buffer_driver_mach_info {
31559393bb9SZhou Zhu 	const char	*name;
31659393bb9SZhou Zhu 	const char	*path_name;
31759393bb9SZhou Zhu 	int	overlay_id;
31859393bb9SZhou Zhu 	int	dmafetch_id;
31959393bb9SZhou Zhu 	int	default_pixfmt;
32059393bb9SZhou Zhu };
32159393bb9SZhou Zhu 
32259393bb9SZhou Zhu /* interface for controllers driver */
32359393bb9SZhou Zhu struct mmp_mach_path_config {
32459393bb9SZhou Zhu 	const char *name;
32559393bb9SZhou Zhu 	int overlay_num;
32659393bb9SZhou Zhu 	int output_type;
32759393bb9SZhou Zhu 	u32 path_config;
32859393bb9SZhou Zhu 	u32 link_config;
3299a27d591SGuoqing Li 	u32 dsi_rbswap;
33059393bb9SZhou Zhu };
33159393bb9SZhou Zhu 
33259393bb9SZhou Zhu struct mmp_mach_plat_info {
33359393bb9SZhou Zhu 	const char *name;
33459393bb9SZhou Zhu 	const char *clk_name;
33559393bb9SZhou Zhu 	int path_num;
33659393bb9SZhou Zhu 	struct mmp_mach_path_config *paths;
33759393bb9SZhou Zhu };
33859393bb9SZhou Zhu 
33959393bb9SZhou Zhu /* interface for panel drivers */
34059393bb9SZhou Zhu struct mmp_mach_panel_info {
34159393bb9SZhou Zhu 	const char *name;
34259393bb9SZhou Zhu 	void (*plat_set_onoff)(int status);
34359393bb9SZhou Zhu 	const char *plat_path_name;
34459393bb9SZhou Zhu };
34559393bb9SZhou Zhu #endif	/* _MMP_DISP_H_ */
346