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