2 * Copyright (C) 2012 Spreadtrum Communications Inc.
\r
11 #include "sprdfb_chip_common.h"
\r
13 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
14 #include "dsi_1_21a/mipi_dsih_local.h"
\r
15 #include "dsi_1_21a/mipi_dsih_dphy.h"
\r
16 #include "dsi_1_21a/mipi_dsih_hal.h"
\r
17 #include "dsi_1_21a/mipi_dsih_api.h"
\r
19 #include "dsi_1_10a/mipi_dsih_local.h"
\r
20 #include "dsi_1_10a/mipi_dsih_dphy.h"
\r
21 #include "dsi_1_10a/mipi_dsih_hal.h"
\r
22 #include "dsi_1_10a/mipi_dsih_api.h"
\r
25 #define DSI_PHY_REF_CLOCK (26*1000)
\r
27 #define DSI_EDPI_CFG (0x6c)
\r
30 struct sprdfb_dsi_context {
\r
33 dsih_ctrl_t dsi_inst;
\r
36 static struct sprdfb_dsi_context dsi_ctx;
\r
38 static void __raw_bits_and(unsigned int v, unsigned int a)
\r
40 __raw_writel((__raw_readl(a) & v), a);
\r
43 static uint32_t dsi_core_read_function(uint32_t addr, uint32_t offset)
\r
45 return __raw_readl(addr + offset);
\r
48 static void dsi_core_write_function(uint32_t addr, uint32_t offset, uint32_t data)
\r
50 __raw_writel(data, addr + offset);
\r
54 static void dsi_reset(void)
\r
56 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
57 __raw_writel(__raw_readl(DSI_AHB_SOFT_RST) | (BIT_DSI_SOFT_RST), DSI_AHB_SOFT_RST);
\r
59 __raw_writel(__raw_readl(DSI_AHB_SOFT_RST) & (~(BIT_DSI_SOFT_RST)),DSI_AHB_SOFT_RST);
\r
62 int32_t dsi_early_int(void)
\r
64 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
66 if(dsi_ctx.is_inited){
\r
67 FB_PRINT("sprdfb: dispc early init warning!(has been inited)");
\r
76 memset(&(dsi_ctx.dsi_inst), 0, sizeof(dsi_ctx.dsi_inst));
\r
78 dsi_ctx.is_inited = 1;
\r
82 static int32_t dsi_edpi_setbuswidth(struct info_mipi * mipi)
\r
84 dsih_color_coding_t color_coding = 0;
\r
86 switch(mipi->video_bus_width){
\r
88 color_coding = COLOR_CODE_16BIT_CONFIG1;
\r
91 color_coding = COLOR_CODE_18BIT_CONFIG1;
\r
94 color_coding = COLOR_CODE_24BIT;
\r
97 printf("sprdfb:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
\r
100 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
101 __raw_bits_or(color_coding,(DSI_CTL_BEGIN+R_DSI_HOST_DPI_COLOR_CODE));
\r
103 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_DPI_CFG, (uint32_t)(color_coding<<2));
\r
109 static int32_t dsi_edpi_init(void)
\r
111 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
112 dsi_core_write_function((uint32_t)DSI_CTL_BEGIN, (uint32_t)R_DSI_HOST_EDPI_CMD_SIZE, 0x500);
\r
114 dsi_core_write_function((uint32_t)DSI_CTL_BEGIN, (uint32_t)R_DSI_HOST_EDPI_CFG, 0x10500);
\r
119 static int32_t dsi_dpi_init(struct sprdfb_device *dev)
\r
121 dsih_dpi_video_t dpi_param = {0};
\r
122 dsih_error_t result;
\r
123 struct panel_spec* panel = dev->panel;
\r
124 struct info_mipi * mipi = panel->info.mipi;
\r
126 dpi_param.no_of_lanes = mipi->lan_number;
\r
127 dpi_param.byte_clock = mipi->phy_feq / 8;
\r
128 #ifndef CONFIG_FPGA
\r
129 dpi_param.pixel_clock = dev->dpi_clock/1000;//384*1000/11;//DSI_PHY_REF_CLOCK / 4;
\r
131 dpi_param.pixel_clock = 6500;
\r
133 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
134 dpi_param.max_hs_to_lp_cycles = 4;//110;
\r
135 dpi_param.max_lp_to_hs_cycles = 15;//10;
\r
136 dpi_param.max_clk_hs_to_lp_cycles = 4;//110;
\r
137 dpi_param.max_clk_lp_to_hs_cycles = 15;//10;
\r
139 switch(mipi->video_bus_width){
\r
141 dpi_param.color_coding = COLOR_CODE_16BIT_CONFIG1;
\r
144 dpi_param.color_coding = COLOR_CODE_18BIT_CONFIG1;
\r
147 dpi_param.color_coding = COLOR_CODE_24BIT;
\r
150 printf("sprdfb:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
\r
154 if(SPRDFB_POLARITY_POS == mipi ->h_sync_pol){
\r
155 dpi_param.h_polarity = 1;
\r
158 if(SPRDFB_POLARITY_POS == mipi ->v_sync_pol){
\r
159 dpi_param.v_polarity = 1;
\r
162 if(SPRDFB_POLARITY_POS == mipi ->de_pol){
\r
163 dpi_param.data_en_polarity = 1;
\r
166 dpi_param.h_active_pixels = panel->width;
\r
167 dpi_param.h_sync_pixels = mipi->timing->hsync;
\r
168 dpi_param.h_back_porch_pixels = mipi->timing->hbp;
\r
169 dpi_param.h_total_pixels = panel->width + mipi->timing->hsync + mipi->timing->hbp + mipi->timing->hfp;
\r
171 dpi_param.v_active_lines = panel->height;
\r
172 dpi_param.v_sync_lines = mipi->timing->vsync;
\r
173 dpi_param.v_back_porch_lines = mipi->timing->vbp;
\r
174 dpi_param.v_total_lines = panel->height + mipi->timing->vsync + mipi->timing->vbp + mipi->timing->vfp;
\r
176 dpi_param.receive_ack_packets = 0;
\r
177 dpi_param.video_mode = VIDEO_BURST_WITH_SYNC_PULSES;
\r
178 dpi_param.virtual_channel = 0;
\r
179 #ifndef CONFIG_FB_LCD_ILI9486S1_MIPI
180 dpi_param.is_18_loosely = 0;
\r
182 dpi_param.is_18_loosely = 1;
\r
185 result = mipi_dsih_dpi_video(&(dsi_ctx.dsi_inst), &dpi_param);
\r
187 printf("sprdfb: [%s] mipi_dsih_dpi_video fail (%d)!\n", __FUNCTION__, result);
\r
194 static void dsi_log_error(const char * string)
\r
200 int32_t sprdfb_dsi_init(struct sprdfb_device *dev)
\r
202 dsih_error_t result = OK;
\r
203 dsih_ctrl_t* dsi_instance = &(dsi_ctx.dsi_inst);
\r
204 dphy_t *phy = &(dsi_instance->phy_instance);
\r
205 struct info_mipi * mipi = dev->panel->info.mipi;
\r
210 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
213 phy->address = DSI_CTL_BEGIN;
\r
214 phy->core_read_function = dsi_core_read_function;
\r
215 phy->core_write_function = dsi_core_write_function;
\r
216 phy->log_error = dsi_log_error;
\r
217 phy->log_info = NULL;
\r
218 phy->reference_freq = DSI_PHY_REF_CLOCK;
\r
219 dsi_instance->address = DSI_CTL_BEGIN;
\r
220 dsi_instance->color_mode_polarity =mipi->color_mode_pol;
\r
221 dsi_instance->shut_down_polarity = mipi->shut_down_pol;
\r
222 dsi_instance->core_read_function = dsi_core_read_function;
\r
223 dsi_instance->core_write_function = dsi_core_write_function;
\r
224 dsi_instance->log_error = dsi_log_error;
\r
225 dsi_instance->log_info = NULL;
\r
226 /*in our rtl implementation, this is max rd time, not bta time and use 15bits*/
\r
227 dsi_instance->max_bta_cycles = 0x6000;//10;
\r
228 #ifndef CONFIG_DSIH_VERSION_1P21A
\r
229 dsi_instance->max_hs_to_lp_cycles = 4;//110;
\r
230 dsi_instance->max_lp_to_hs_cycles = 15;//10;
\r
232 dsi_instance->max_lanes = mipi->lan_number;
\r
234 if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
\r
237 dsi_dpi_init(dev->panel);
\r
241 result = mipi_dsih_unregister_all_events(dsi_instance);
\r
243 FB_PRINT("sprdfb: [%s]: mipi_dsih_unregister_all_events fail (%d)!\n", __FUNCTION__, result);
\r
247 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
248 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_INT_MSK0, 0x1fffff);
\r
249 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_INT_MSK1, 0x3ffff);
\r
251 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_MSK0, 0x1fffff);
\r
252 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_MSK1, 0x3ffff);
\r
254 dsi_instance->phy_feq = dev->panel->info.mipi->phy_feq;
\r
256 result = mipi_dsih_open(dsi_instance);
\r
258 printf("sprdfb: [%s]: mipi_dsih_open fail (%d)!\n", __FUNCTION__, result);
\r
262 result = mipi_dsih_dphy_configure(phy, mipi->lan_number, mipi->phy_feq);
\r
264 printf("sprdfb: [%s]: mipi_dsih_dphy_configure fail (%d)!\n", __FUNCTION__, result);
\r
268 while(5 != (dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_STATUS) & 5)){
\r
269 if(0x0 == ++i%500000){
\r
270 printf("sprdfb: [%s] warning: busy waiting!\n", __FUNCTION__);
\r
274 if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
\r
275 dsi_edpi_setbuswidth(mipi);
\r
278 result = mipi_dsih_enable_rx(dsi_instance, 1);
\r
280 printf("sprdfb: [%s]: mipi_dsih_enable_rx fail (%d)!\n", __FUNCTION__, result);
\r
284 result = mipi_dsih_ecc_rx(dsi_instance, 1);
\r
286 printf("sprdfb: [%s]: mipi_dsih_ecc_rx fail (%d)!\n", __FUNCTION__, result);
\r
290 result = mipi_dsih_eotp_rx(dsi_instance, 1);
\r
292 printf("sprdfb: [%s]: mipi_dsih_eotp_rx fail (%d)!\n", __FUNCTION__, result);
\r
296 result = mipi_dsih_eotp_tx(dsi_instance, 1);
\r
298 printf("sprdfb: [%s]: mipi_dsih_eotp_tx fail (%d)!\n", __FUNCTION__, result);
\r
302 if(SPRDFB_MIPI_MODE_VIDEO == mipi->work_mode){
\r
306 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
307 mipi_dsih_dphy_enable_nc_clk(&(dsi_instance->phy_instance), 0);
\r
313 int32_t sprdfb_dsi_uninit(struct sprdfb_device *dev)
\r
315 dsih_error_t result;
\r
316 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
317 mipi_dsih_dphy_enable_hs_clk(&(dsi_ctx.dsi_inst.phy_instance), 0);
\r
319 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0);
\r
322 result = mipi_dsih_close(&(dsi_ctx.dsi_inst));
\r
324 printf("sprdfb: [%s]: sprdfb_dsi_uninit fail (%d)!\n", __FUNCTION__, result);
\r
327 dsi_ctx.dsi_inst.status = NOT_INITIALIZED;
\r
328 dsi_ctx.is_inited = 0;
\r
336 int32_t sprdfb_dsi_ready(struct sprdfb_device *dev)
\r
338 struct info_mipi * mipi = dev->panel->info.mipi;
\r
340 if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
\r
341 mipi_dsih_cmd_mode(&(dsi_ctx.dsi_inst), 1);
\r
342 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
343 mipi_dsih_dphy_enable_hs_clk(&(dsi_ctx.dsi_inst.phy_instance), 1);
\r
344 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x0);
\r
346 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x1);
\r
347 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0x1);
\r
350 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
351 mipi_dsih_dphy_enable_hs_clk(&(dsi_ctx.dsi_inst.phy_instance), 1);
\r
353 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0x1);
\r
355 mipi_dsih_video_mode(&(dsi_ctx.dsi_inst), 1);
\r
356 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PWR_UP, 0);
\r
358 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PWR_UP, 1);
\r
360 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
361 dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_INT_ST0);
\r
362 dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_INT_ST1);
\r
364 dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_ST0);
\r
365 dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_ST1);
\r
372 static int32_t sprdfb_dsi_set_lp_mode(void)
\r
375 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
377 mipi_dsih_cmd_mode(&(dsi_ctx.dsi_inst), 1);
\r
378 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
379 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x01ffff00);
\r
380 mipi_dsih_dphy_enable_hs_clk(&(dsi_ctx.dsi_inst.phy_instance), 0);
\r
382 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x1fff);
\r
383 reg_val = dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL);
\r
384 reg_val = reg_val & (~(BIT(0)));
\r
385 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, reg_val);
\r
390 static int32_t sprdfb_dsi_set_hs_mode(void)
\r
392 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
394 mipi_dsih_cmd_mode(&(dsi_ctx.dsi_inst), 1);
\r
395 #ifdef CONFIG_DSIH_VERSION_1P21A
\r
396 mipi_dsih_dphy_enable_hs_clk(&(dsi_ctx.dsi_inst.phy_instance), 1);
\r
397 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x0);
\r
399 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x1);
\r
400 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0x1);
\r
405 int32_t sprdfb_dsi_before_panel_reset(struct sprdfb_device *dev)
\r
407 sprdfb_dsi_set_lp_mode();
\r
411 static int32_t sprdfb_dsi_set_cmd_mode(void)
\r
413 mipi_dsih_cmd_mode(&(dsi_ctx.dsi_inst), 1);
\r
417 static int32_t sprdfb_dsi_set_video_mode(void)
\r
419 mipi_dsih_video_mode(&(dsi_ctx.dsi_inst), 1);
\r
423 static int32_t sprdfb_dsi_gen_write(uint8_t *param, uint16_t param_length)
\r
425 dsih_error_t result;
\r
427 result = mipi_dsih_gen_wr_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length);
\r
430 printf("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
436 #define LCM_SEND(len) ((1 << 24)| len)
437 #define LCM_TAG_MASK ((1 << 24) -1)
439 static unsigned char set_bl_seq[] = {
442 void backlight_control(int brigtness)
444 set_bl_seq[1] = brigtness;
445 printf("%s : %d\n", __func__, brigtness);
446 sprdfb_dsi_gen_write(set_bl_seq, LCM_SEND(2) & LCM_TAG_MASK);
448 EXPORT_SYMBOL(backlight_control);
450 static int32_t sprdfb_dsi_gen_read(uint8_t *param, uint16_t param_length, uint8_t bytes_to_read, uint8_t *read_buffer)
\r
453 result = mipi_dsih_gen_rd_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length, bytes_to_read, read_buffer);
\r
455 printf("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
461 static int32_t sprdfb_dsi_dcs_write(uint8_t *param, uint16_t param_length)
\r
463 dsih_error_t result;
\r
464 result = mipi_dsih_dcs_wr_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length);
\r
466 printf("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
472 static int32_t sprdfb_dsi_dcs_read(uint8_t command, uint8_t bytes_to_read, uint8_t *read_buffer)
\r
475 result = mipi_dsih_dcs_rd_cmd(&(dsi_ctx.dsi_inst), 0, command, bytes_to_read, read_buffer);
\r
477 printf("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
483 static int32_t sprd_dsi_force_write(uint8_t data_type, uint8_t *p_params, uint16_t param_length)
\r
487 iRtn = mipi_dsih_gen_wr_packet(&(dsi_ctx.dsi_inst), 0, data_type, p_params, param_length);
\r
492 static int32_t sprd_dsi_force_read(uint8_t command, uint8_t bytes_to_read, uint8_t * read_buffer)
\r
496 iRtn = mipi_dsih_gen_rd_packet(&(dsi_ctx.dsi_inst), 0, 6, 0, command, bytes_to_read, read_buffer);
\r
501 static int32_t sprd_dsi_eotp_set(uint8_t rx_en, uint8_t tx_en)
\r
503 dsih_ctrl_t *curInstancePtr = &(dsi_ctx.dsi_inst);
\r
505 mipi_dsih_eotp_rx(curInstancePtr, 0);
\r
506 else if(1 == rx_en)
\r
507 mipi_dsih_eotp_rx(curInstancePtr, 1);
\r
509 mipi_dsih_eotp_tx(curInstancePtr, 0);
\r
510 else if(1 == tx_en)
\r
511 mipi_dsih_eotp_tx(curInstancePtr, 1);
\r
515 struct ops_mipi sprdfb_mipi_ops = {
\r
516 .mipi_set_cmd_mode = sprdfb_dsi_set_cmd_mode,
\r
517 .mipi_set_video_mode = sprdfb_dsi_set_video_mode,
\r
518 .mipi_set_lp_mode = sprdfb_dsi_set_lp_mode,
\r
519 .mipi_set_hs_mode = sprdfb_dsi_set_hs_mode,
\r
520 .mipi_gen_write = sprdfb_dsi_gen_write,
\r
521 .mipi_gen_read = sprdfb_dsi_gen_read,
\r
522 .mipi_dcs_write = sprdfb_dsi_dcs_write,
\r
523 .mipi_dcs_read = sprdfb_dsi_dcs_read,
\r
524 .mipi_force_write = sprd_dsi_force_write,
\r
525 .mipi_force_read = sprd_dsi_force_read,
\r
526 .mipi_eotp_set = sprd_dsi_eotp_set,
\r