2 * Copyright (C) 2012 Spreadtrum Communications Inc.
\r
4 * This software is licensed under the terms of the GNU General Public
\r
5 * License version 2, as published by the Free Software Foundation, and
\r
6 * may be copied, distributed, and modified under those terms.
\r
8 * This program is distributed in the hope that it will be useful,
\r
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
11 * GNU General Public License for more details.
\r
15 #include <asm/arch/tiger_lcd.h>
\r
18 #include <asm/arch/sc8810_reg_ahb.h>
\r
19 #include <asm/arch/sc8810_reg_base.h>
24 #include "mipi_dsih_local.h"
\r
25 #include "mipi_dsih_dphy.h"
\r
26 #include "mipi_dsih_hal.h"
\r
27 #include "mipi_dsih_api.h"
\r
29 #define DSI_SOFT_RST (26)
\r
30 #define DSI_PHY_REF_CLOCK (26*1000)
\r
32 #define DSI_EDPI_CFG (0x6c)
\r
35 struct sprdfb_dsi_context {
\r
38 dsih_ctrl_t dsi_inst;
\r
41 static struct sprdfb_dsi_context dsi_ctx;
\r
43 static void __raw_bits_and(unsigned int v, unsigned int a)
45 __raw_writel((__raw_readl(a) & v), a);
48 static void __raw_bits_or(unsigned int v, unsigned int a)
50 __raw_writel((__raw_readl(a) | v), a);
54 static uint32_t dsi_core_read_function(uint32_t addr, uint32_t offset)
\r
56 return __raw_readl(addr + offset);
\r
59 static void dsi_core_write_function(uint32_t addr, uint32_t offset, uint32_t data)
\r
61 __raw_writel(data, addr + offset);
\r
65 static void dsi_reset(void)
\r
67 __raw_writel(__raw_readl(AHB_SOFT_RST) | (1<<DSI_SOFT_RST), AHB_SOFT_RST);
\r
69 __raw_writel(__raw_readl(AHB_SOFT_RST) & (~(1<<DSI_SOFT_RST)),AHB_SOFT_RST);
\r
72 int32_t dsi_early_int(void)
\r
74 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
76 if(dsi_ctx.is_inited){
\r
77 FB_PRINT("sprdfb: dispc early init warning!(has been inited)");
\r
81 //TODO:Enable DSI clock
\r
85 memset(&(dsi_ctx.dsi_inst), 0, sizeof(dsi_ctx.dsi_inst));
\r
87 dsi_ctx.is_inited = 1;
\r
91 static int32_t dsi_edpi_setbuswidth(struct info_mipi * mipi)
93 dsih_color_coding_t color_coding = 0;
\r
95 switch(mipi->video_bus_width){
\r
97 color_coding = COLOR_CODE_16BIT_CONFIG1;
\r
100 color_coding = COLOR_CODE_18BIT_CONFIG1;
\r
103 color_coding = COLOR_CODE_24BIT;
\r
106 FB_PRINT("sprdfb:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
\r
110 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_DPI_CFG, (uint32_t)(color_coding<<2));
\r
115 static int32_t dsi_edpi_init(void)
\r
117 dsi_core_write_function((uint32_t)DSI_CTL_BEGIN, (uint32_t)DSI_EDPI_CFG, 0x10500);
121 static int32_t dsi_dpi_init(struct panel_spec* panel)
\r
123 dsih_dpi_video_t dpi_param;
\r
124 dsih_error_t result;
\r
125 struct info_mipi * mipi = panel->info.mipi;
\r
127 dpi_param.no_of_lanes = mipi->lan_number;
\r
128 dpi_param.byte_clock = mipi->phy_feq / 8;
\r
129 dpi_param.pixel_clock = 384*1000/11;//DSI_PHY_REF_CLOCK / 4;
\r
131 switch(mipi->video_bus_width){
\r
133 dpi_param.color_coding = COLOR_CODE_16BIT_CONFIG1;
\r
136 dpi_param.color_coding = COLOR_CODE_18BIT_CONFIG1;
\r
139 dpi_param.color_coding = COLOR_CODE_24BIT;
\r
142 FB_PRINT("sprdfb:[%s] fail, invalid video_bus_width\n", __FUNCTION__);
\r
146 //if(SPRDFB_POLARITY_POS == mipi ->h_sync_pol){
\r
147 dpi_param.h_polarity = 1;
\r
150 //if(SPRDFB_POLARITY_POS == mipi ->v_sync_pol){
\r
151 dpi_param.v_polarity = 1;
\r
154 //if(SPRDFB_POLARITY_POS == mipi ->de_pol){
\r
155 dpi_param.data_en_polarity = 1;
\r
158 dpi_param.h_active_pixels = panel->width;
\r
159 dpi_param.h_sync_pixels = mipi->timing->hsync;
\r
160 dpi_param.h_back_porch_pixels = mipi->timing->hbp;
\r
161 dpi_param.h_total_pixels = panel->width + mipi->timing->hsync + mipi->timing->hbp + mipi->timing->hfp;
\r
163 dpi_param.v_active_lines = panel->height;
\r
164 dpi_param.v_sync_lines = mipi->timing->vsync;
\r
165 dpi_param.v_back_porch_lines = mipi->timing->vbp;
\r
166 dpi_param.v_total_lines = panel->height + mipi->timing->vsync + mipi->timing->vbp + mipi->timing->vfp;
\r
168 dpi_param.receive_ack_packets = 0;
\r
169 dpi_param.video_mode = VIDEO_BURST_WITH_SYNC_PULSES;
\r
170 dpi_param.virtual_channel = 0;
\r
171 dpi_param.is_18_loosely = 0;
\r
173 result = mipi_dsih_dpi_video(&(dsi_ctx.dsi_inst), &dpi_param);
\r
175 FB_PRINT("sprdfb: [%s] mipi_dsih_dpi_video fail (%d)!\n", __FUNCTION__, result);
\r
182 static void dsi_log_error(const char * string)
\r
188 int32_t sprdfb_dsi_init(struct sprdfb_device *dev)
\r
190 dsih_error_t result = OK;
\r
191 dsih_ctrl_t* dsi_instance = &(dsi_ctx.dsi_inst);
\r
192 dphy_t *phy = &(dsi_instance->phy_instance);
\r
193 struct info_mipi * mipi = dev->panel->info.mipi;
\r
195 __raw_bits_or((1<<0), 0x2090021c); //enable dphy
\r
197 FB_PRINT("sprdfb:[%s]\n", __FUNCTION__);
\r
201 phy->address = DSI_CTL_BEGIN;
\r
202 phy->core_read_function = dsi_core_read_function;
\r
203 phy->core_write_function = dsi_core_write_function;
\r
204 phy->log_error = dsi_log_error;
\r
205 phy->log_info = NULL;
\r
206 phy->reference_freq = DSI_PHY_REF_CLOCK;
\r
208 dsi_instance->address = DSI_CTL_BEGIN;
\r
209 dsi_instance->color_mode_polarity =SPRDFB_POLARITY_NEG; //mipi->color_mode_pol;
\r
210 dsi_instance->shut_down_polarity = SPRDFB_POLARITY_NEG; //mipi->shut_down_pol;
\r
211 dsi_instance->core_read_function = dsi_core_read_function;
\r
212 dsi_instance->core_write_function = dsi_core_write_function;
\r
213 dsi_instance->log_error = dsi_log_error;
\r
214 dsi_instance->log_info = NULL;
\r
215 /*in our rtl implementation, this is max rd time, not bta time and use 15bits*/
\r
216 dsi_instance->max_bta_cycles = 0x6000;//10;
\r
217 dsi_instance->max_hs_to_lp_cycles = 4;//110;
\r
218 dsi_instance->max_lp_to_hs_cycles = 15;//10;
\r
219 dsi_instance->max_lanes = mipi->lan_number;
\r
221 if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
\r
224 dsi_dpi_init(dev->panel);
\r
228 result = mipi_dsih_unregister_all_events(dsi_instance);
\r
230 FB_PRINT("sprdfb: [%s]: mipi_dsih_unregister_all_events fail (%d)!\n", __FUNCTION__, result);
\r
234 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_MSK0, 0x1fffff);
\r
235 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_MSK1, 0x3ffff);
\r
237 result = mipi_dsih_open(dsi_instance);
\r
239 FB_PRINT("sprdfb: [%s]: mipi_dsih_open fail (%d)!\n", __FUNCTION__, result);
\r
243 result = mipi_dsih_dphy_configure(phy, mipi->lan_number, mipi->phy_feq);
\r
245 FB_PRINT("sprdfb: [%s]: mipi_dsih_dphy_configure fail (%d)!\n", __FUNCTION__, result);
\r
249 while(5 != (dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_STATUS) & 5));
\r
251 if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
\r
252 dsi_edpi_setbuswidth(mipi);
\r
255 result = mipi_dsih_enable_rx(dsi_instance, 1);
\r
257 FB_PRINT("sprdfb: [%s]: mipi_dsih_enable_rx fail (%d)!\n", __FUNCTION__, result);
\r
261 result = mipi_dsih_ecc_rx(dsi_instance, 1);
\r
263 FB_PRINT("sprdfb: [%s]: mipi_dsih_ecc_rx fail (%d)!\n", __FUNCTION__, result);
\r
267 result = mipi_dsih_eotp_rx(dsi_instance, 1);
\r
269 FB_PRINT("sprdfb: [%s]: mipi_dsih_eotp_rx fail (%d)!\n", __FUNCTION__, result);
\r
273 result = mipi_dsih_eotp_tx(dsi_instance, 1);
\r
275 FB_PRINT("sprdfb: [%s]: mipi_dsih_eotp_tx fail (%d)!\n", __FUNCTION__, result);
\r
279 if(SPRDFB_MIPI_MODE_VIDEO == mipi->work_mode){
\r
280 dsi_dpi_init(dev->panel);
\r
286 int32_t sprdfb_dsi_uninit(struct sprdfb_device *dev)
\r
288 dsih_error_t result;
\r
289 result = mipi_dsih_close(&(dsi_ctx.dsi_inst));
\r
291 FB_PRINT("sprdfb: [%s]: sprdfb_dsi_uninit fail (%d)!\n", __FUNCTION__, result);
\r
294 dsi_ctx.is_inited = 0;
\r
297 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0);
\r
303 int32_t sprdfb_dsi_ready(struct sprdfb_device *dev)
\r
305 struct info_mipi * mipi = dev->panel->info.mipi;
\r
307 if(SPRDFB_MIPI_MODE_CMD == mipi->work_mode){
\r
308 mipi_dsih_cmd_mode(&(dsi_ctx.dsi_inst), 1);
\r
309 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_CMD_MODE_CFG, 0x1);
\r
310 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PHY_IF_CTRL, 0x1);
\r
312 mipi_dsih_video_mode(&(dsi_ctx.dsi_inst), 1);
\r
313 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PWR_UP, 0);
\r
315 dsi_core_write_function(DSI_CTL_BEGIN, R_DSI_HOST_PWR_UP, 1);
\r
317 dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_ST0);
\r
318 dsi_core_read_function(DSI_CTL_BEGIN, R_DSI_HOST_ERROR_ST1);
\r
323 static int32_t sprdfb_dsi_set_cmd_mode(void)
\r
325 mipi_dsih_cmd_mode(&(dsi_ctx.dsi_inst), 1);
\r
329 static int32_t sprdfb_dsi_set_video_mode(void)
\r
331 mipi_dsih_video_mode(&(dsi_ctx.dsi_inst), 1);
\r
335 static int32_t sprdfb_dsi_gen_write(uint8_t *param, uint16_t param_length)
\r
337 dsih_error_t result;
\r
338 result = mipi_dsih_gen_wr_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length);
\r
340 FB_PRINT("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
346 static int32_t sprdfb_dsi_gen_read(uint8_t *param, uint16_t param_length, uint8_t bytes_to_read, uint8_t *read_buffer)
\r
349 result = mipi_dsih_gen_rd_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length, bytes_to_read, read_buffer);
\r
351 FB_PRINT("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
357 static int32_t sprdfb_dsi_dcs_write(uint8_t *param, uint16_t param_length)
\r
359 dsih_error_t result;
\r
360 result = mipi_dsih_dcs_wr_cmd(&(dsi_ctx.dsi_inst), 0, param, param_length);
\r
362 FB_PRINT("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
368 static int32_t sprdfb_dsi_dcs_read(uint8_t command, uint8_t bytes_to_read, uint8_t *read_buffer)
\r
371 result = mipi_dsih_dcs_rd_cmd(&(dsi_ctx.dsi_inst), 0, command, bytes_to_read, read_buffer);
\r
373 FB_PRINT("sprdfb: [%s] error (%d)\n", __FUNCTION__, result);
\r
379 static int32_t sprd_dsi_force_write(uint8_t data_type, uint8_t *p_params, uint16_t param_length)
\r
382 iRtn = mipi_dsih_gen_wr_packet(&(dsi_ctx.dsi_inst), 0, data_type, p_params, param_length);
\r
386 static int32_t sprd_dsi_force_read(uint8_t command, uint8_t bytes_to_read, uint8_t * read_buffer)
\r
389 dsih_ctrl_t *curInstancePtr = &(dsi_ctx.dsi_inst);
\r
391 mipi_dsih_eotp_rx(curInstancePtr, 0);
\r
392 mipi_dsih_eotp_tx(curInstancePtr, 0);
\r
394 iRtn = mipi_dsih_gen_rd_packet(&(dsi_ctx.dsi_inst), 0, 6, 0, command, bytes_to_read, read_buffer);
\r
396 mipi_dsih_eotp_rx(curInstancePtr, 1);
\r
397 mipi_dsih_eotp_tx(curInstancePtr, 1);
\r
402 struct ops_mipi sprdfb_mipi_ops = {
\r
403 .mipi_set_cmd_mode = sprdfb_dsi_set_cmd_mode,
\r
404 .mipi_set_video_mode = sprdfb_dsi_set_video_mode,
\r
405 .mipi_gen_write = sprdfb_dsi_gen_write,
\r
406 .mipi_gen_read = sprdfb_dsi_gen_read,
\r
407 .mipi_dcs_write = sprdfb_dsi_dcs_write,
\r
408 .mipi_dcs_read = sprdfb_dsi_dcs_read,
\r
409 .mipi_force_write = sprd_dsi_force_write,
\r
410 .mipi_force_read = sprd_dsi_force_read,
\r