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