| /* 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; |
| |
| const 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[] __counted_by(overlay_num); |
| }; |
| |
| 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); |
| const 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_ */ |