1/* 2 * Copyright © 2010 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * jim liu <jim.liu@intel.com> 25 * Jackie Li<yaodong.li@intel.com> 26 */ 27 28#ifndef __MDFLD_DSI_OUTPUT_H__ 29#define __MDFLD_DSI_OUTPUT_H__ 30 31#include <linux/backlight.h> 32#include <drm/drmP.h> 33#include <drm/drm.h> 34#include <drm/drm_crtc.h> 35#include <drm/drm_edid.h> 36 37#include "psb_drv.h" 38#include "psb_intel_drv.h" 39#include "psb_intel_reg.h" 40#include "mdfld_output.h" 41 42#include <asm/intel-mid.h> 43 44#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) 45#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) 46#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end)) 47#define FLD_MOD(orig, val, start, end) \ 48 (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) 49 50#define REG_FLD_MOD(reg, val, start, end) \ 51 REG_WRITE(reg, FLD_MOD(REG_READ(reg), val, start, end)) 52 53static inline int REGISTER_FLD_WAIT(struct drm_device *dev, u32 reg, 54 u32 val, int start, int end) 55{ 56 int t = 100000; 57 58 while (FLD_GET(REG_READ(reg), start, end) != val) { 59 if (--t == 0) 60 return 1; 61 } 62 63 return 0; 64} 65 66#define REG_FLD_WAIT(reg, val, start, end) \ 67 REGISTER_FLD_WAIT(dev, reg, val, start, end) 68 69#define REG_BIT_WAIT(reg, val, bitnum) \ 70 REGISTER_FLD_WAIT(dev, reg, val, bitnum, bitnum) 71 72#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 73 74#ifdef DEBUG 75#define CHECK_PIPE(pipe) ({ \ 76 const typeof(pipe) __pipe = (pipe); \ 77 BUG_ON(__pipe != 0 && __pipe != 2); \ 78 __pipe; }) 79#else 80#define CHECK_PIPE(pipe) (pipe) 81#endif 82 83/* 84 * Actual MIPIA->MIPIC reg offset is 0x800, value 0x400 is valid for 0 and 2 85 */ 86#define REG_OFFSET(pipe) (CHECK_PIPE(pipe) * 0x400) 87 88/* mdfld DSI controller registers */ 89#define MIPI_DEVICE_READY_REG(pipe) (0xb000 + REG_OFFSET(pipe)) 90#define MIPI_INTR_STAT_REG(pipe) (0xb004 + REG_OFFSET(pipe)) 91#define MIPI_INTR_EN_REG(pipe) (0xb008 + REG_OFFSET(pipe)) 92#define MIPI_DSI_FUNC_PRG_REG(pipe) (0xb00c + REG_OFFSET(pipe)) 93#define MIPI_HS_TX_TIMEOUT_REG(pipe) (0xb010 + REG_OFFSET(pipe)) 94#define MIPI_LP_RX_TIMEOUT_REG(pipe) (0xb014 + REG_OFFSET(pipe)) 95#define MIPI_TURN_AROUND_TIMEOUT_REG(pipe) (0xb018 + REG_OFFSET(pipe)) 96#define MIPI_DEVICE_RESET_TIMER_REG(pipe) (0xb01c + REG_OFFSET(pipe)) 97#define MIPI_DPI_RESOLUTION_REG(pipe) (0xb020 + REG_OFFSET(pipe)) 98#define MIPI_DBI_FIFO_THROTTLE_REG(pipe) (0xb024 + REG_OFFSET(pipe)) 99#define MIPI_HSYNC_COUNT_REG(pipe) (0xb028 + REG_OFFSET(pipe)) 100#define MIPI_HBP_COUNT_REG(pipe) (0xb02c + REG_OFFSET(pipe)) 101#define MIPI_HFP_COUNT_REG(pipe) (0xb030 + REG_OFFSET(pipe)) 102#define MIPI_HACTIVE_COUNT_REG(pipe) (0xb034 + REG_OFFSET(pipe)) 103#define MIPI_VSYNC_COUNT_REG(pipe) (0xb038 + REG_OFFSET(pipe)) 104#define MIPI_VBP_COUNT_REG(pipe) (0xb03c + REG_OFFSET(pipe)) 105#define MIPI_VFP_COUNT_REG(pipe) (0xb040 + REG_OFFSET(pipe)) 106#define MIPI_HIGH_LOW_SWITCH_COUNT_REG(pipe) (0xb044 + REG_OFFSET(pipe)) 107#define MIPI_DPI_CONTROL_REG(pipe) (0xb048 + REG_OFFSET(pipe)) 108#define MIPI_DPI_DATA_REG(pipe) (0xb04c + REG_OFFSET(pipe)) 109#define MIPI_INIT_COUNT_REG(pipe) (0xb050 + REG_OFFSET(pipe)) 110#define MIPI_MAX_RETURN_PACK_SIZE_REG(pipe) (0xb054 + REG_OFFSET(pipe)) 111#define MIPI_VIDEO_MODE_FORMAT_REG(pipe) (0xb058 + REG_OFFSET(pipe)) 112#define MIPI_EOT_DISABLE_REG(pipe) (0xb05c + REG_OFFSET(pipe)) 113#define MIPI_LP_BYTECLK_REG(pipe) (0xb060 + REG_OFFSET(pipe)) 114#define MIPI_LP_GEN_DATA_REG(pipe) (0xb064 + REG_OFFSET(pipe)) 115#define MIPI_HS_GEN_DATA_REG(pipe) (0xb068 + REG_OFFSET(pipe)) 116#define MIPI_LP_GEN_CTRL_REG(pipe) (0xb06c + REG_OFFSET(pipe)) 117#define MIPI_HS_GEN_CTRL_REG(pipe) (0xb070 + REG_OFFSET(pipe)) 118#define MIPI_GEN_FIFO_STAT_REG(pipe) (0xb074 + REG_OFFSET(pipe)) 119#define MIPI_HS_LS_DBI_ENABLE_REG(pipe) (0xb078 + REG_OFFSET(pipe)) 120#define MIPI_DPHY_PARAM_REG(pipe) (0xb080 + REG_OFFSET(pipe)) 121#define MIPI_DBI_BW_CTRL_REG(pipe) (0xb084 + REG_OFFSET(pipe)) 122#define MIPI_CLK_LANE_SWITCH_TIME_CNT_REG(pipe) (0xb088 + REG_OFFSET(pipe)) 123 124#define MIPI_CTRL_REG(pipe) (0xb104 + REG_OFFSET(pipe)) 125#define MIPI_DATA_ADD_REG(pipe) (0xb108 + REG_OFFSET(pipe)) 126#define MIPI_DATA_LEN_REG(pipe) (0xb10c + REG_OFFSET(pipe)) 127#define MIPI_CMD_ADD_REG(pipe) (0xb110 + REG_OFFSET(pipe)) 128#define MIPI_CMD_LEN_REG(pipe) (0xb114 + REG_OFFSET(pipe)) 129 130/* non-uniform reg offset */ 131#define MIPI_PORT_CONTROL(pipe) (CHECK_PIPE(pipe) ? MIPI_C : MIPI) 132 133#define DSI_DEVICE_READY (0x1) 134#define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1) 135#define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1) 136#define DSI_POWER_STATE_ULPS_OFFSET (0x1) 137 138 139#define DSI_ONE_DATA_LANE (0x1) 140#define DSI_TWO_DATA_LANE (0x2) 141#define DSI_THREE_DATA_LANE (0X3) 142#define DSI_FOUR_DATA_LANE (0x4) 143#define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3) 144#define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5) 145#define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7) 146#define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7) 147#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7) 148#define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7) 149#define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13) 150 151#define DSI_INTR_STATE_RXSOTERROR BIT(0) 152 153#define DSI_INTR_STATE_SPL_PKG_SENT BIT(30) 154#define DSI_INTR_STATE_TE BIT(31) 155 156#define DSI_HS_TX_TIMEOUT_MASK (0xffffff) 157 158#define DSI_LP_RX_TIMEOUT_MASK (0xffffff) 159 160#define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f) 161 162#define DSI_RESET_TIMER_MASK (0xffff) 163 164#define DSI_DBI_FIFO_WM_HALF (0x0) 165#define DSI_DBI_FIFO_WM_QUARTER (0x1) 166#define DSI_DBI_FIFO_WM_LOW (0x2) 167 168#define DSI_DPI_TIMING_MASK (0xffff) 169 170#define DSI_INIT_TIMER_MASK (0xffff) 171 172#define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff) 173 174#define DSI_LP_BYTECLK_MASK (0x0ffff) 175 176#define DSI_HS_CTRL_GEN_SHORT_W0 (0x03) 177#define DSI_HS_CTRL_GEN_SHORT_W1 (0x13) 178#define DSI_HS_CTRL_GEN_SHORT_W2 (0x23) 179#define DSI_HS_CTRL_GEN_R0 (0x04) 180#define DSI_HS_CTRL_GEN_R1 (0x14) 181#define DSI_HS_CTRL_GEN_R2 (0x24) 182#define DSI_HS_CTRL_GEN_LONG_W (0x29) 183#define DSI_HS_CTRL_MCS_SHORT_W0 (0x05) 184#define DSI_HS_CTRL_MCS_SHORT_W1 (0x15) 185#define DSI_HS_CTRL_MCS_R0 (0x06) 186#define DSI_HS_CTRL_MCS_LONG_W (0x39) 187#define DSI_HS_CTRL_VC_OFFSET (0x06) 188#define DSI_HS_CTRL_WC_OFFSET (0x08) 189 190#define DSI_FIFO_GEN_HS_DATA_FULL BIT(0) 191#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY BIT(1) 192#define DSI_FIFO_GEN_HS_DATA_EMPTY BIT(2) 193#define DSI_FIFO_GEN_LP_DATA_FULL BIT(8) 194#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY BIT(9) 195#define DSI_FIFO_GEN_LP_DATA_EMPTY BIT(10) 196#define DSI_FIFO_GEN_HS_CTRL_FULL BIT(16) 197#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY BIT(17) 198#define DSI_FIFO_GEN_HS_CTRL_EMPTY BIT(18) 199#define DSI_FIFO_GEN_LP_CTRL_FULL BIT(24) 200#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY BIT(25) 201#define DSI_FIFO_GEN_LP_CTRL_EMPTY BIT(26) 202#define DSI_FIFO_DBI_EMPTY BIT(27) 203#define DSI_FIFO_DPI_EMPTY BIT(28) 204 205#define DSI_DBI_HS_LP_SWITCH_MASK (0x1) 206 207#define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0) 208#define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16) 209 210#define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001) 211#define DSI_DPI_CTRL_HS_TURN_ON (0x00000002) 212 213/*dsi power modes*/ 214#define DSI_POWER_MODE_DISPLAY_ON BIT(2) 215#define DSI_POWER_MODE_NORMAL_ON BIT(3) 216#define DSI_POWER_MODE_SLEEP_OUT BIT(4) 217#define DSI_POWER_MODE_PARTIAL_ON BIT(5) 218#define DSI_POWER_MODE_IDLE_ON BIT(6) 219 220enum { 221 MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1, 222 MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2, 223 MDFLD_DSI_VIDEO_BURST_MODE = 3, 224}; 225 226#define DSI_DPI_COMPLETE_LAST_LINE BIT(2) 227#define DSI_DPI_DISABLE_BTA BIT(3) 228 229struct mdfld_dsi_connector { 230 struct gma_connector base; 231 232 int pipe; 233 void *private; 234 void *pkg_sender; 235 236 /* Connection status */ 237 enum drm_connector_status status; 238}; 239 240struct mdfld_dsi_encoder { 241 struct gma_encoder base; 242 void *private; 243}; 244 245/* 246 * DSI config, consists of one DSI connector, two DSI encoders. 247 * DRM will pick up on DSI encoder basing on differents configs. 248 */ 249struct mdfld_dsi_config { 250 struct drm_device *dev; 251 struct drm_display_mode *fixed_mode; 252 struct drm_display_mode *mode; 253 254 struct mdfld_dsi_connector *connector; 255 struct mdfld_dsi_encoder *encoder; 256 257 int changed; 258 259 int bpp; 260 int lane_count; 261 /*Virtual channel number for this encoder*/ 262 int channel_num; 263 /*video mode configure*/ 264 int video_mode; 265 266 int dvr_ic_inited; 267}; 268 269static inline struct mdfld_dsi_connector *mdfld_dsi_connector( 270 struct drm_connector *connector) 271{ 272 struct gma_connector *gma_connector; 273 274 gma_connector = to_gma_connector(connector); 275 276 return container_of(gma_connector, struct mdfld_dsi_connector, base); 277} 278 279static inline struct mdfld_dsi_encoder *mdfld_dsi_encoder( 280 struct drm_encoder *encoder) 281{ 282 struct gma_encoder *gma_encoder; 283 284 gma_encoder = to_gma_encoder(encoder); 285 286 return container_of(gma_encoder, struct mdfld_dsi_encoder, base); 287} 288 289static inline struct mdfld_dsi_config * 290 mdfld_dsi_get_config(struct mdfld_dsi_connector *connector) 291{ 292 if (!connector) 293 return NULL; 294 return (struct mdfld_dsi_config *)connector->private; 295} 296 297static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config) 298{ 299 struct mdfld_dsi_connector *dsi_connector; 300 301 if (!config) 302 return NULL; 303 304 dsi_connector = config->connector; 305 306 if (!dsi_connector) 307 return NULL; 308 309 return dsi_connector->pkg_sender; 310} 311 312static inline struct mdfld_dsi_config * 313 mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder) 314{ 315 if (!encoder) 316 return NULL; 317 return (struct mdfld_dsi_config *)encoder->private; 318} 319 320static inline struct mdfld_dsi_connector * 321 mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder) 322{ 323 struct mdfld_dsi_config *config; 324 325 if (!encoder) 326 return NULL; 327 328 config = mdfld_dsi_encoder_get_config(encoder); 329 if (!config) 330 return NULL; 331 332 return config->connector; 333} 334 335static inline void *mdfld_dsi_encoder_get_pkg_sender( 336 struct mdfld_dsi_encoder *encoder) 337{ 338 struct mdfld_dsi_config *dsi_config; 339 340 dsi_config = mdfld_dsi_encoder_get_config(encoder); 341 if (!dsi_config) 342 return NULL; 343 344 return mdfld_dsi_get_pkg_sender(dsi_config); 345} 346 347static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder) 348{ 349 struct mdfld_dsi_connector *connector; 350 351 if (!encoder) 352 return -1; 353 354 connector = mdfld_dsi_encoder_get_connector(encoder); 355 if (!connector) 356 return -1; 357 return connector->pipe; 358} 359 360/* Export functions */ 361extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev, 362 u32 gen_fifo_stat_reg, u32 fifo_stat); 363extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, 364 int pipe); 365extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, 366 int level); 367extern void mdfld_dsi_output_init(struct drm_device *dev, 368 int pipe, 369 const struct panel_funcs *p_vid_funcs); 370extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, 371 int pipe); 372 373extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, 374 u32 *mode, bool hs); 375extern int mdfld_dsi_panel_reset(int pipe); 376 377#endif /*__MDFLD_DSI_OUTPUT_H__*/ 378