/* * Copyright (C) ST-Ericsson SA 2010 * * ST-Ericsson MCDE base driver * * Author: Marcus Lorentzon * for ST-Ericsson. * * License terms: GNU General Public License (GPL), version 2. */ #ifndef __MCDE__H__ #define __MCDE__H__ #include /* REVIEW: Remove */ /* Physical interface types */ enum mcde_port_type { MCDE_PORTTYPE_DSI = 0, MCDE_PORTTYPE_DPI = 1, MCDE_PORTTYPE_DBI = 2, /* REVIEW: Remove */ }; /* Interface mode */ enum mcde_port_mode { MCDE_PORTMODE_CMD = 0, MCDE_PORTMODE_VID = 1, }; /* MCDE fifos */ enum mcde_fifo { MCDE_FIFO_A = 0, MCDE_FIFO_B = 1, MCDE_FIFO_C0 = 2, MCDE_FIFO_C1 = 3, }; /* MCDE channels (pixel pipelines) */ enum mcde_chnl { MCDE_CHNL_A = 0, MCDE_CHNL_B = 1, MCDE_CHNL_C0 = 2, MCDE_CHNL_C1 = 3, }; /* Channel path */ #define MCDE_CHNLPATH(__chnl, __fifo, __type, __ifc, __link) \ (((__chnl) << 16) | ((__fifo) << 12) | \ ((__type) << 8) | ((__ifc) << 4) | ((__link) << 0)) enum mcde_chnl_path { /* Channel A */ MCDE_CHNLPATH_CHNLA_FIFOA_DPI_0 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_A, MCDE_PORTTYPE_DPI, 0, 0), MCDE_CHNLPATH_CHNLA_FIFOA_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 0), MCDE_CHNLPATH_CHNLA_FIFOA_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 1), MCDE_CHNLPATH_CHNLA_FIFOC0_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 0, 2), MCDE_CHNLPATH_CHNLA_FIFOC0_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 0), MCDE_CHNLPATH_CHNLA_FIFOC0_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 1), MCDE_CHNLPATH_CHNLA_FIFOA_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_A, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 1, 2), /* Channel B */ MCDE_CHNLPATH_CHNLB_FIFOB_DPI_1 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_B, MCDE_PORTTYPE_DPI, 0, 1), MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 0), MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 1), MCDE_CHNLPATH_CHNLB_FIFOC1_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 0, 2), MCDE_CHNLPATH_CHNLB_FIFOC1_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 0), MCDE_CHNLPATH_CHNLB_FIFOC1_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 1), MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_B, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 1, 2), /* Channel C0 */ MCDE_CHNLPATH_CHNLC0_FIFOC0_DBI_0 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_C0, MCDE_PORTTYPE_DBI, 0, 0), MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 0), MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 1), MCDE_CHNLPATH_CHNLC0_FIFOC0_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 0, 2), MCDE_CHNLPATH_CHNLC0_FIFOC0_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 0), MCDE_CHNLPATH_CHNLC0_FIFOC0_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 1), MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_C0, MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 1, 2), /* Channel C1 */ MCDE_CHNLPATH_CHNLC1_FIFOC1_DBI_1 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_C1, MCDE_PORTTYPE_DBI, 0, 1), MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 0), MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 1), MCDE_CHNLPATH_CHNLC1_FIFOC1_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 0, 2), MCDE_CHNLPATH_CHNLC1_FIFOC1_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 0), MCDE_CHNLPATH_CHNLC1_FIFOC1_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 1), MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_C1, MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 1, 2), }; /* Update sync mode */ enum mcde_sync_src { MCDE_SYNCSRC_OFF = 0, /* No sync */ MCDE_SYNCSRC_TE0 = 1, /* MCDE ext TE0 */ MCDE_SYNCSRC_TE1 = 2, /* MCDE ext TE1 */ MCDE_SYNCSRC_BTA = 3, /* DSI BTA */ MCDE_SYNCSRC_EXT = 4, /* GPIO, or other outside MCDE control */ };/* REVIEW: Remove _EXT, not supported */ /* Interface pixel formats (output) */ /* REVIEW: Define formats */ enum mcde_port_pix_fmt { /* MIPI standard formats */ MCDE_PORTPIXFMT_DBI_3BPP = 0x11,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DBI_8BPP = 0x12,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DBI_12BPP = 0x13,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DBI_16BPP = 0x15,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DBI_18BPP = 0x16,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DBI_24BPP = 0x17,/* REVIEW: Remove */ MCDE_PORTPIXFMT_DPI_16BPP_C1 = 0x21, MCDE_PORTPIXFMT_DPI_16BPP_C2 = 0x22, MCDE_PORTPIXFMT_DPI_16BPP_C3 = 0x23, MCDE_PORTPIXFMT_DPI_18BPP_C1 = 0x24, MCDE_PORTPIXFMT_DPI_18BPP_C2 = 0x25, MCDE_PORTPIXFMT_DPI_24BPP = 0x26, MCDE_PORTPIXFMT_DSI_16BPP = 0x31, MCDE_PORTPIXFMT_DSI_18BPP = 0x32, MCDE_PORTPIXFMT_DSI_18BPP_PACKED = 0x33, MCDE_PORTPIXFMT_DSI_24BPP = 0x34, /* Custom formats */ MCDE_PORTPIXFMT_DSI_YCBCR422 = 0x40, }; struct mcde_col_convert { u16 matrix[3][3]; u16 offset[3]; }; struct mcde_port { enum mcde_port_type type; enum mcde_port_mode mode; enum mcde_port_pix_fmt pixel_format; u8 ifc; u8 link; enum mcde_sync_src sync_src; bool update_auto_trig; union { struct { u8 virt_id; u8 num_data_lanes; u8 ui; bool clk_cont; } dsi; struct { bool chip_select;/* REVIEW: Used? Needed? */ u8 num_data_lanes;/* REVIEW: Rename to bus_width? */ } dpi; } phy; }; /* Overlay pixel formats (input) *//* REVIEW: Define byte order */ enum mcde_ovly_pix_fmt { MCDE_OVLYPIXFMT_RGB565 = 1, MCDE_OVLYPIXFMT_RGBA5551 = 2, MCDE_OVLYPIXFMT_RGBA4444 = 3, MCDE_OVLYPIXFMT_RGB888 = 4, MCDE_OVLYPIXFMT_RGBX8888 = 5, MCDE_OVLYPIXFMT_RGBA8888 = 6, MCDE_OVLYPIXFMT_YCbCr422 = 7,/* REVIEW: Capitalize */ }; /* Display power modes */ enum mcde_display_power_mode { MCDE_DISPLAY_PM_OFF = 0, /* Power off */ MCDE_DISPLAY_PM_STANDBY = 1, /* DCS sleep mode */ MCDE_DISPLAY_PM_ON = 2, /* DCS normal mode, display on */ }; /* Display rotation */ enum mcde_display_rotation { MCDE_DISPLAY_ROT_0 = 0, MCDE_DISPLAY_ROT_90_CCW = 90, MCDE_DISPLAY_ROT_180_CCW = 180, MCDE_DISPLAY_ROT_270_CCW = 270, MCDE_DISPLAY_ROT_90_CW = MCDE_DISPLAY_ROT_270_CCW, MCDE_DISPLAY_ROT_180_CW = MCDE_DISPLAY_ROT_180_CCW, MCDE_DISPLAY_ROT_270_CW = MCDE_DISPLAY_ROT_90_CCW, }; /* REVIEW: Verify */ #define MCDE_MIN_WIDTH 16 #define MCDE_MIN_HEIGHT 16 #define MCDE_MAX_WIDTH 2048 #define MCDE_MAX_HEIGHT 2048 #define MCDE_BUF_START_ALIGMENT 8 #define MCDE_BUF_LINE_ALIGMENT 8 #define MCDE_FIFO_AB_SIZE 640 #define MCDE_FIFO_C0C1_SIZE 160 #define MCDE_PIXFETCH_LARGE_WTRMRKLVL 128 #define MCDE_PIXFETCH_MEDIUM_WTRMRKLVL 64 #define MCDE_PIXFETCH_SMALL_WTRMRKLVL 16 /* Video mode descriptor */ struct mcde_video_mode {/* REVIEW: Join 1 & 2 */ u32 xres; u32 yres; u32 pixclock; /* pixel clock in ps (pico seconds) */ u32 hbp; /* hor back porch = left_margin */ u32 hfp; /* hor front porch equals to right_margin */ u32 vbp1; /* field 1: vert back porch equals to upper_margin */ u32 vfp1; /* field 1: vert front porch equals to lower_margin */ u32 vbp2; /* field 2: vert back porch equals to upper_margin */ u32 vfp2; /* field 2: vert front porch equals to lower_margin */ bool interlaced; }; struct mcde_rectangle { u16 x; u16 y; u16 w; u16 h; }; struct mcde_overlay_info { u32 paddr; u16 stride; /* buffer line len in bytes */ enum mcde_ovly_pix_fmt fmt; u16 src_x; u16 src_y; u16 dst_x; u16 dst_y; u16 dst_z; u16 w; u16 h; struct mcde_rectangle dirty; }; struct mcde_overlay { struct kobject kobj; struct list_head list; /* mcde_display_device.ovlys */ struct mcde_display_device *ddev; struct mcde_overlay_info info; struct mcde_ovly_state *state; }; struct mcde_chnl_state; struct mcde_chnl_state *mcde_chnl_get(enum mcde_chnl chnl_id, enum mcde_fifo fifo, const struct mcde_port *port); int mcde_chnl_set_pixel_format(struct mcde_chnl_state *chnl, enum mcde_port_pix_fmt pix_fmt); void mcde_chnl_set_col_convert(struct mcde_chnl_state *chnl, struct mcde_col_convert *col_convert); int mcde_chnl_set_video_mode(struct mcde_chnl_state *chnl, struct mcde_video_mode *vmode); /* TODO: Remove rotbuf* parameters */ int mcde_chnl_set_rotation(struct mcde_chnl_state *chnl, enum mcde_display_rotation rotation, u32 rotbuf1, u32 rotbuf2); int mcde_chnl_enable_synchronized_update(struct mcde_chnl_state *chnl, bool enable); int mcde_chnl_set_power_mode(struct mcde_chnl_state *chnl, enum mcde_display_power_mode power_mode); int mcde_chnl_apply(struct mcde_chnl_state *chnl); int mcde_chnl_update(struct mcde_chnl_state *chnl, struct mcde_rectangle *update_area); void mcde_chnl_put(struct mcde_chnl_state *chnl); /* MCDE overlay */ struct mcde_ovly_state; struct mcde_ovly_state *mcde_ovly_get(struct mcde_chnl_state *chnl); void mcde_ovly_set_source_buf(struct mcde_ovly_state *ovly, u32 paddr); void mcde_ovly_set_source_info(struct mcde_ovly_state *ovly, u32 stride, enum mcde_ovly_pix_fmt pix_fmt); void mcde_ovly_set_source_area(struct mcde_ovly_state *ovly, u16 x, u16 y, u16 w, u16 h); void mcde_ovly_set_dest_pos(struct mcde_ovly_state *ovly, u16 x, u16 y, u8 z); void mcde_ovly_apply(struct mcde_ovly_state *ovly); void mcde_ovly_put(struct mcde_ovly_state *ovly); /* MCDE dsi */ #define DCS_CMD_ENTER_IDLE_MODE 0x39 #define DCS_CMD_ENTER_INVERT_MODE 0x21 #define DCS_CMD_ENTER_NORMAL_MODE 0x13 #define DCS_CMD_ENTER_PARTIAL_MODE 0x12 #define DCS_CMD_ENTER_SLEEP_MODE 0x10 #define DCS_CMD_EXIT_IDLE_MODE 0x38 #define DCS_CMD_EXIT_INVERT_MODE 0x20 #define DCS_CMD_EXIT_SLEEP_MODE 0x11 #define DCS_CMD_GET_ADDRESS_MODE 0x0B #define DCS_CMD_GET_BLUE_CHANNEL 0x08 #define DCS_CMD_GET_DIAGNOSTIC_RESULT 0x0F #define DCS_CMD_GET_DISPLAY_MODE 0x0D #define DCS_CMD_GET_GREEN_CHANNEL 0x07 #define DCS_CMD_GET_PIXEL_FORMAT 0x0C #define DCS_CMD_GET_POWER_MODE 0x0A #define DCS_CMD_GET_RED_CHANNEL 0x06 #define DCS_CMD_GET_SCANLINE 0x45 #define DCS_CMD_GET_SIGNAL_MODE 0x0E #define DCS_CMD_NOP 0x00 #define DCS_CMD_READ_DDB_CONTINUE 0xA8 #define DCS_CMD_READ_DDB_START 0xA1 #define DCS_CMD_READ_MEMORY_CONTINE 0x3E #define DCS_CMD_READ_MEMORY_START 0x2E #define DCS_CMD_SET_ADDRESS_MODE 0x36 #define DCS_CMD_SET_COLUMN_ADDRESS 0x2A #define DCS_CMD_SET_DISPLAY_OFF 0x28 #define DCS_CMD_SET_DISPLAY_ON 0x29 #define DCS_CMD_SET_GAMMA_CURVE 0x26 #define DCS_CMD_SET_PAGE_ADDRESS 0x2B #define DCS_CMD_SET_PARTIAL_AREA 0x30 #define DCS_CMD_SET_PIXEL_FORMAT 0x3A #define DCS_CMD_SET_SCROLL_AREA 0x33 #define DCS_CMD_SET_SCROLL_START 0x37 #define DCS_CMD_SET_TEAR_OFF 0x34 #define DCS_CMD_SET_TEAR_ON 0x35 #define DCS_CMD_SET_TEAR_SCANLINE 0x44 #define DCS_CMD_SOFT_RESET 0x01 #define DCS_CMD_WRITE_LUT 0x2D #define DCS_CMD_WRITE_CONTINUE 0x3C #define DCS_CMD_WRITE_START 0x2C #define MCDE_MAX_DCS_READ 4 #define MCDE_MAX_DCS_WRITE 15 int mcde_dsi_dcs_write(struct mcde_chnl_state *chnl, u8 cmd, u8* data, int len); int mcde_dsi_dcs_read(struct mcde_chnl_state *chnl, u8 cmd, u8* data, int *len); /* MCDE */ /* Driver data */ #define MCDE_IRQ "MCDE IRQ" #define MCDE_IO_AREA "MCDE I/O Area" struct mcde_platform_data { /* DSI */ int num_dsilinks; /* DBI/DPI */ u8 outmux[5]; /* MCDE_CONF0.OUTMUXx */ u8 syncmux; /* MCDE_CONF0.SYNCMUXx */ const char *regulator_id; const char *clock_dsi_id; const char *clock_dsi_lp_id; const char *clock_mcde_id; }; int mcde_init(void); void mcde_exit(void); #endif /* __MCDE__H__ */