/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * linux/include/video/mmp_disp.h * Header file for Marvell MMP Display Controller * * Copyright (C) 2012 Marvell Technology Group Ltd. * Authors: Zhou Zhu <zzhu3@marvell.com> */ #ifndef _MMP_DISP_H_ #define _MMP_DISP_H_ #include <linux/kthread.h> enum { PIXFMT_UYVY = 0, PIXFMT_VYUY, PIXFMT_YUYV, PIXFMT_YUV422P, PIXFMT_YVU422P, PIXFMT_YUV420P, PIXFMT_YVU420P, PIXFMT_RGB565 = 0x100, PIXFMT_BGR565, PIXFMT_RGB1555, PIXFMT_BGR1555, PIXFMT_RGB888PACK, PIXFMT_BGR888PACK, PIXFMT_RGB888UNPACK, PIXFMT_BGR888UNPACK, PIXFMT_RGBA888, PIXFMT_BGRA888, PIXFMT_RGB666, /* for output usage */ PIXFMT_PSEUDOCOLOR = 0x200, }; static inline int pixfmt_to_stride(int pix_fmt) { switch (pix_fmt) { case PIXFMT_RGB565: case PIXFMT_BGR565: case PIXFMT_RGB1555: case PIXFMT_BGR1555: case PIXFMT_UYVY: case PIXFMT_VYUY: case PIXFMT_YUYV: return 2; case PIXFMT_RGB888UNPACK: case PIXFMT_BGR888UNPACK: case PIXFMT_RGBA888: case PIXFMT_BGRA888: return 4; case PIXFMT_RGB888PACK: case PIXFMT_BGR888PACK: return 3; case PIXFMT_YUV422P: case PIXFMT_YVU422P: case PIXFMT_YUV420P: case PIXFMT_YVU420P: case PIXFMT_PSEUDOCOLOR: return 1; default: return 0; } } /* parameters used by path/overlay */ /* overlay related para: win/addr */ struct mmp_win { /* position/size of window */ u16 xsrc; u16 ysrc; u16 xdst; u16 ydst; u16 xpos; u16 ypos; u16 left_crop; u16 right_crop; u16 up_crop; u16 bottom_crop; int pix_fmt; /* * pitch[0]: graphics/video layer line length or y pitch * pitch[1]/pitch[2]: video u/v pitch if non-zero */ u32 pitch[3]; }; struct mmp_addr { /* phys address */ u32 phys[6]; }; /* path related para: mode */ struct mmp_mode { const char *name; u32 refresh; u32 xres; u32 yres; u32 left_margin; u32 right_margin; u32 upper_margin; u32 lower_margin; u32 hsync_len; u32 vsync_len; u32 hsync_invert; u32 vsync_invert; u32 invert_pixclock; u32 pixclock_freq; int pix_fmt_out; }; /* main structures */ struct mmp_path; struct mmp_overlay; struct mmp_panel; /* status types */ enum { MMP_OFF = 0, MMP_ON, }; static inline const char *stat_name(int stat) { switch (stat) { case MMP_OFF: return "OFF"; case MMP_ON: return "ON"; default: return "UNKNOWNSTAT"; } } struct mmp_overlay_ops { /* should be provided by driver */ void (*set_fetch)(struct mmp_overlay *overlay, int fetch_id); void (*set_onoff)(struct mmp_overlay *overlay, int status); void (*set_win)(struct mmp_overlay *overlay, struct mmp_win *win); int (*set_addr)(struct mmp_overlay *overlay, struct mmp_addr *addr); }; /* overlay describes a z-order indexed slot in each path. */ struct mmp_overlay { int id; const char *name; struct mmp_path *path; /* overlay info: private data */ int dmafetch_id; struct mmp_addr addr; struct mmp_win win; /* state */ int open_count; int status; struct mutex access_ok; struct mmp_overlay_ops *ops; }; /* panel type */ enum { PANELTYPE_ACTIVE = 0, PANELTYPE_SMART, PANELTYPE_TV, PANELTYPE_DSI_CMD, PANELTYPE_DSI_VIDEO, }; struct mmp_panel { /* use node to register to list */ struct list_head node; const char *name; /* path name used to connect to proper path configed */ const char *plat_path_name; struct device *dev; int panel_type; void *plat_data; int (*get_modelist)(struct mmp_panel *panel, struct mmp_mode **modelist); void (*set_mode)(struct mmp_panel *panel, struct mmp_mode *mode); void (*set_onoff)(struct mmp_panel *panel, int status); }; struct mmp_path_ops { int (*check_status)(struct mmp_path *path); struct mmp_overlay *(*get_overlay)(struct mmp_path *path, int overlay_id); int (*get_modelist)(struct mmp_path *path, struct mmp_mode **modelist); /* follow ops should be provided by driver */ void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode); void (*set_onoff)(struct mmp_path *path, int status); /* todo: add query */ }; /* path output types */ enum { PATH_OUT_PARALLEL, PATH_OUT_DSI, PATH_OUT_HDMI, }; /* path is main part of mmp-disp */ struct mmp_path { /* use node to register to list */ struct list_head node; /* init data */ struct device *dev; int id; const char *name; int output_type; struct mmp_panel *panel; void *plat_data; /* dynamic use */ struct mmp_mode mode; /* state */ int open_count; int status; struct mutex access_ok; struct mmp_path_ops ops; /* layers */ int overlay_num; struct mmp_overlay overlays[0]; }; extern struct mmp_path *mmp_get_path(const char *name); static inline void mmp_path_set_mode(struct mmp_path *path, struct mmp_mode *mode) { if (path) path->ops.set_mode(path, mode); } static inline void mmp_path_set_onoff(struct mmp_path *path, int status) { if (path) path->ops.set_onoff(path, status); } static inline int mmp_path_get_modelist(struct mmp_path *path, struct mmp_mode **modelist) { if (path) return path->ops.get_modelist(path, modelist); return 0; } static inline struct mmp_overlay *mmp_path_get_overlay( struct mmp_path *path, int overlay_id) { if (path) return path->ops.get_overlay(path, overlay_id); return NULL; } static inline void mmp_overlay_set_fetch(struct mmp_overlay *overlay, int fetch_id) { if (overlay) overlay->ops->set_fetch(overlay, fetch_id); } static inline void mmp_overlay_set_onoff(struct mmp_overlay *overlay, int status) { if (overlay) overlay->ops->set_onoff(overlay, status); } static inline void mmp_overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win) { if (overlay) overlay->ops->set_win(overlay, win); } static inline int mmp_overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr) { if (overlay) return overlay->ops->set_addr(overlay, addr); return 0; } /* * driver data is set from each detailed ctrl driver for path usage * it defined a common interface that plat driver need to implement */ struct mmp_path_info { /* driver data, set when registed*/ const char *name; struct device *dev; int id; int output_type; int overlay_num; void (*set_mode)(struct mmp_path *path, struct mmp_mode *mode); void (*set_onoff)(struct mmp_path *path, int status); struct mmp_overlay_ops *overlay_ops; void *plat_data; }; extern struct mmp_path *mmp_register_path( struct mmp_path_info *info); extern void mmp_unregister_path(struct mmp_path *path); extern void mmp_register_panel(struct mmp_panel *panel); extern void mmp_unregister_panel(struct mmp_panel *panel); /* defintions for platform data */ /* interface for buffer driver */ struct mmp_buffer_driver_mach_info { const char *name; const char *path_name; int overlay_id; int dmafetch_id; int default_pixfmt; }; /* interface for controllers driver */ struct mmp_mach_path_config { const char *name; int overlay_num; int output_type; u32 path_config; u32 link_config; u32 dsi_rbswap; }; struct mmp_mach_plat_info { const char *name; const char *clk_name; int path_num; struct mmp_mach_path_config *paths; }; /* interface for panel drivers */ struct mmp_mach_panel_info { const char *name; void (*plat_set_onoff)(int status); const char *plat_path_name; }; #endif /* _MMP_DISP_H_ */