2 #include "mipi_dsih_api.h"
\r
3 #include "mipi_dsih_hal.h"
\r
4 #include "mipi_dsih_dphy.h"
\r
5 /* whether to get debug messages (1) or not (0) */
\r
8 #define PRECISION_FACTOR 1000
\r
9 #define VIDEO_PACKET_OVERHEAD 6
\r
10 #define NULL_PACKET_OVERHEAD 6
\r
11 #define SHORT_PACKET 4
\r
12 #define BLANKING_PACKET 6
\r
13 #define MAX_NULL_SIZE 1023
\r
15 static const uint32_t mipi_dsih_supported_versions[] = {0x3130302A, 0x3130312A, 0x3131302A};
\r
16 static const uint32_t mipi_dsih_no_of_versions = sizeof(mipi_dsih_supported_versions) / sizeof(uint32_t);
\r
18 dsih_error_t mipi_dsih_open(dsih_ctrl_t * instance)
\r
20 dsih_error_t err = OK;
\r
21 uint32_t version = 0;
\r
27 return ERR_DSI_INVALID_INSTANCE;
\r
29 else if ((instance->core_read_function == 0) || (instance->core_write_function == 0))
\r
31 return ERR_DSI_INVALID_IO;
\r
33 else if (instance->status == INITIALIZED)
\r
35 return ERR_DSI_INVALID_INSTANCE;
\r
37 else if (mipi_dsih_dphy_open(&(instance->phy_instance)))
\r
39 return ERR_DSI_PHY_INVALID;
\r
43 instance->status = NOT_INITIALIZED;
\r
44 version = mipi_dsih_hal_get_version(instance);
\r
45 for (i = 0; i < mipi_dsih_no_of_versions; i++)
\r
47 if (version == mipi_dsih_supported_versions[i])
\r
52 /* no matching supported version has been found*/
\r
53 if (i >= mipi_dsih_no_of_versions)
\r
55 if (instance->log_info != 0)
\r
57 instance->log_info("driver does not support this core version 0x%lX", version);
\r
59 return ERR_DSI_CORE_INCOMPATIBLE;
\r
62 //mipi_dsih_hal_power(instance, 0);//Jessica
\r
63 //mipi_dsih_hal_power(instance, 1);//Jessica
\r
64 mipi_dsih_hal_dpi_color_mode_pol(instance, !instance->color_mode_polarity);
\r
65 mipi_dsih_hal_dpi_shut_down_pol(instance, !instance->shut_down_polarity);
\r
66 err = mipi_dsih_phy_hs2lp_config(instance, instance->max_hs_to_lp_cycles);
\r
67 err |= mipi_dsih_phy_lp2hs_config(instance, instance->max_lp_to_hs_cycles);
\r
68 err |= mipi_dsih_phy_bta_time(instance, instance->max_bta_cycles);
\r
71 return ERR_DSI_OVERFLOW;
\r
73 /* by default, return to LP during ALL, unless otherwise specified*/
\r
74 mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);
\r
75 mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);
\r
76 mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);
\r
77 mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);
\r
78 mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);
\r
79 mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);
\r
80 /* by default, all commands are sent in LP */
\r
81 mipi_dsih_hal_dcs_wr_tx_type(instance, 0, 1);
\r
82 mipi_dsih_hal_dcs_wr_tx_type(instance, 1, 1);
\r
83 mipi_dsih_hal_dcs_wr_tx_type(instance, 3, 1); /* long packet*/
\r
84 mipi_dsih_hal_dcs_rd_tx_type(instance, 0, 1);
\r
85 /*Jessica add to support max rd packet size command*/
\r
86 mipi_dsih_hal_max_rd_packet_size_type(instance, 1);
\r
87 mipi_dsih_hal_gen_wr_tx_type(instance, 0, 1);
\r
88 mipi_dsih_hal_gen_wr_tx_type(instance, 1, 1);
\r
89 mipi_dsih_hal_gen_wr_tx_type(instance, 2, 1);
\r
90 mipi_dsih_hal_gen_wr_tx_type(instance, 3, 1); /* long packet*/
\r
91 mipi_dsih_hal_gen_rd_tx_type(instance, 0, 1);
\r
92 mipi_dsih_hal_gen_rd_tx_type(instance, 1, 1);
\r
93 mipi_dsih_hal_gen_rd_tx_type(instance, 2, 1);
\r
94 /* by default, RX_VC = 0, NO EOTp, EOTn, BTA, ECC rx and CRC rx */
\r
95 mipi_dsih_hal_gen_rd_vc(instance, 0);
\r
96 mipi_dsih_hal_gen_eotp_rx_en(instance, 0);
\r
97 mipi_dsih_hal_gen_eotp_tx_en(instance, 0);
\r
98 mipi_dsih_hal_bta_en(instance, 0);
\r
99 mipi_dsih_hal_gen_ecc_rx_en(instance, 0);
\r
100 mipi_dsih_hal_gen_crc_rx_en(instance, 0);
\r
101 mipi_dsih_hal_power(instance, 0);//Jessica
\r
102 mipi_dsih_hal_power(instance, 1);//Jessica
\r
103 /* initialize pll so escape clocks could be generated at 864MHz, 1 lane */
\r
104 /* however the high speed clock will not be requested */
\r
105 //err = mipi_dsih_dphy_configure(&(instance->phy_instance), 1, DEFAULT_BYTE_CLOCK);
\r
107 err = mipi_dsih_dphy_configure(&(instance->phy_instance), instance->max_lanes, 190*1000);
\r
110 return err; /* ERR_DSI_PHY_POWERUP; */
\r
113 /* dividing by 6 is aimed for max PHY frequency, 1GHz */
\r
114 mipi_dsih_hal_tx_escape_division(instance, 3); //6 //Jessica
\r
115 instance->status = INITIALIZED;
\r
118 dsih_error_t mipi_dsih_close(dsih_ctrl_t * instance)
\r
122 return ERR_DSI_INVALID_INSTANCE;
\r
124 if (instance->status != INITIALIZED)
\r
126 return ERR_DSI_INVALID_INSTANCE;
\r
128 mipi_dsih_dphy_close(&(instance->phy_instance));
\r
129 mipi_dsih_hal_power(instance, 0);
\r
132 void mipi_dsih_allow_return_to_lp(dsih_ctrl_t * instance, int hfp, int hbp, int vactive, int vfp, int vbp, int vsync)
\r
139 if (instance->status == INITIALIZED)
\r
141 mipi_dsih_hal_dpi_lp_during_hfp(instance, hfp);
\r
142 mipi_dsih_hal_dpi_lp_during_hbp(instance, hbp);
\r
143 mipi_dsih_hal_dpi_lp_during_vactive(instance, vactive);
\r
144 mipi_dsih_hal_dpi_lp_during_vfp(instance, vfp);
\r
145 mipi_dsih_hal_dpi_lp_during_vbp(instance, vbp);
\r
146 mipi_dsih_hal_dpi_lp_during_vsync(instance, vsync);
\r
150 if (instance->log_error != 0)
\r
152 instance->log_error("invalid instance");
\r
155 void mipi_dsih_dcs_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)
\r
162 if (instance->status == INITIALIZED)
\r
164 mipi_dsih_hal_dcs_wr_tx_type(instance, 0, short_write);
\r
165 mipi_dsih_hal_dcs_wr_tx_type(instance, 1, short_write);
\r
166 mipi_dsih_hal_dcs_wr_tx_type(instance, 3, long_write); /* long packet*/
\r
167 mipi_dsih_hal_dcs_rd_tx_type(instance, 0, short_read);
\r
171 if (instance->log_error != 0)
\r
173 instance->log_error("invalid instance");
\r
176 void mipi_dsih_gen_cmd_lp_transmission(dsih_ctrl_t * instance, int long_write, int short_write, int short_read)
\r
183 if (instance->status == INITIALIZED)
\r
185 mipi_dsih_hal_gen_wr_tx_type(instance, 0, short_write);
\r
186 mipi_dsih_hal_gen_wr_tx_type(instance, 1, short_write);
\r
187 mipi_dsih_hal_gen_wr_tx_type(instance, 2, short_write);
\r
188 mipi_dsih_hal_gen_wr_tx_type(instance, 3, long_write); /* long packet*/
\r
189 mipi_dsih_hal_gen_rd_tx_type(instance, 0, short_read);
\r
190 mipi_dsih_hal_gen_rd_tx_type(instance, 1, short_read);
\r
191 mipi_dsih_hal_gen_rd_tx_type(instance, 2, short_read);
\r
195 if (instance->log_error != 0)
\r
197 instance->log_error("invalid instance");
\r
200 /* packet handling */
\r
201 dsih_error_t mipi_dsih_enable_rx(dsih_ctrl_t * instance, int enable)
\r
203 mipi_dsih_hal_bta_en(instance, enable);
\r
206 dsih_error_t mipi_dsih_peripheral_ack(dsih_ctrl_t * instance, int enable)
\r
210 if (instance->status == INITIALIZED)
\r
212 mipi_dsih_hal_cmd_ack_en(instance, enable);
\r
215 mipi_dsih_hal_bta_en(instance, 1);
\r
220 return ERR_DSI_INVALID_INSTANCE;
\r
222 dsih_error_t mipi_dsih_tear_effect_ack(dsih_ctrl_t * instance, int enable)
\r
226 if (instance->status == INITIALIZED)
\r
228 mipi_dsih_hal_tear_effect_ack_en(instance, enable);
\r
231 mipi_dsih_hal_bta_en(instance, 1);
\r
236 return ERR_DSI_INVALID_INSTANCE;
\r
238 dsih_error_t mipi_dsih_eotp_rx(dsih_ctrl_t * instance, int enable)
\r
242 if (instance->status == INITIALIZED)
\r
244 mipi_dsih_hal_gen_eotp_rx_en(instance, enable);
\r
247 mipi_dsih_hal_bta_en(instance, 1);
\r
252 return ERR_DSI_INVALID_INSTANCE;
\r
254 dsih_error_t mipi_dsih_ecc_rx(dsih_ctrl_t * instance, int enable)
\r
258 if (instance->status == INITIALIZED)
\r
260 mipi_dsih_hal_gen_ecc_rx_en(instance, enable);
\r
263 mipi_dsih_hal_bta_en(instance, 1);
\r
268 return ERR_DSI_INVALID_INSTANCE;
\r
270 dsih_error_t mipi_dsih_eotp_tx(dsih_ctrl_t * instance, int enable)
\r
274 if (instance->status == INITIALIZED)
\r
276 mipi_dsih_hal_gen_eotp_tx_en(instance, enable);
\r
280 return ERR_DSI_INVALID_INSTANCE;
\r
282 dsih_error_t mipi_dsih_dpi_video(dsih_ctrl_t * instance, dsih_dpi_video_t * video_params)
\r
284 dsih_error_t err_code = OK;
\r
285 uint16_t bytes_per_pixel_x100 = 0; /* bpp x 100 because it can be 2.25 */
\r
286 uint16_t video_size = 0;
\r
287 uint32_t ratio_clock_xPF = 0; /* holds dpi clock/byte clock times precision factor */
\r
288 uint16_t null_packet_size = 0;
\r
289 uint8_t video_size_step = 1;
\r
290 uint32_t hs_timeout = 0;
\r
291 uint32_t total_bytes = 0;
\r
292 uint32_t bytes_per_chunk = 0;
\r
293 uint32_t no_of_chunks = 0;
\r
294 uint32_t bytes_left = 0;
\r
295 uint32_t chunk_overhead = 0;
\r
297 /* check DSI controller instance */
\r
298 if ((instance == 0) || (video_params == 0))
\r
300 return ERR_DSI_INVALID_INSTANCE;
\r
302 if (instance->status != INITIALIZED)
\r
304 return ERR_DSI_INVALID_INSTANCE;
\r
306 /* set up phy pll to required lane clock */
\r
308 //err_code = mipi_dsih_dphy_configure(&(instance->phy_instance), video_params->no_of_lanes, video_params->byte_clock * 8);
\r
311 // return err_code;
\r
314 ratio_clock_xPF = (video_params->byte_clock * PRECISION_FACTOR) / (video_params->pixel_clock);
\r
315 video_size = video_params->h_active_pixels;
\r
316 /* set up ACKs and error reporting */
\r
317 mipi_dsih_hal_dpi_frame_ack_en(instance, video_params->receive_ack_packets);
\r
318 if (video_params->receive_ack_packets)
\r
319 { /* if ACK is requested, enable BTA, otherwise leave as is */
\r
320 mipi_dsih_hal_bta_en(instance, 1);
\r
322 mipi_dsih_hal_gen_cmd_mode_en(instance, 0);
\r
323 mipi_dsih_hal_dpi_video_mode_en(instance, 1);
\r
324 /* get bytes per pixel and video size step (depending if loosely or not */
\r
325 switch (video_params->color_coding)
\r
327 case COLOR_CODE_16BIT_CONFIG1:
\r
328 case COLOR_CODE_16BIT_CONFIG2:
\r
329 case COLOR_CODE_16BIT_CONFIG3:
\r
330 bytes_per_pixel_x100 = 200;
\r
331 video_size_step = 1;
\r
333 case COLOR_CODE_18BIT_CONFIG1:
\r
334 case COLOR_CODE_18BIT_CONFIG2:
\r
335 mipi_dsih_hal_dpi_18_loosely_packet_en(instance, video_params->is_18_loosely);
\r
336 bytes_per_pixel_x100 = 225;
\r
337 if (!video_params->is_18_loosely)
\r
338 { /* 18bits per pixel and NOT loosely, packets should be multiples of 4 */
\r
339 video_size_step = 4;
\r
340 /* round up active H pixels to a multiple of 4 */
\r
341 for (; (video_size % 4) != 0; video_size++)
\r
348 video_size_step = 1;
\r
351 case COLOR_CODE_24BIT:
\r
352 bytes_per_pixel_x100 = 300;
\r
353 video_size_step = 1;
\r
356 if (instance->log_error != 0)
\r
358 instance->log_error("invalid color coding");
\r
360 err_code = ERR_DSI_COLOR_CODING;
\r
363 if (err_code == OK)
\r
365 err_code = mipi_dsih_hal_dpi_color_coding(instance, video_params->color_coding);
\r
367 if (err_code != OK)
\r
371 mipi_dsih_hal_dpi_video_mode_type(instance, video_params->video_mode);
\r
372 mipi_dsih_hal_dpi_hline(instance, (uint16_t)(((video_params->h_total_pixels) * ratio_clock_xPF) / PRECISION_FACTOR));
\r
373 mipi_dsih_hal_dpi_hbp(instance, ((video_params->h_back_porch_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
\r
374 mipi_dsih_hal_dpi_hsa(instance, ((video_params->h_sync_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
\r
375 mipi_dsih_hal_dpi_vactive(instance, video_params->v_active_lines);
\r
376 mipi_dsih_hal_dpi_vfp(instance, video_params->v_total_lines - (video_params->v_back_porch_lines + video_params->v_sync_lines + video_params->v_active_lines));
\r
377 mipi_dsih_hal_dpi_vbp(instance, video_params->v_back_porch_lines);
\r
378 mipi_dsih_hal_dpi_vsync(instance, video_params->v_sync_lines);
\r
379 mipi_dsih_hal_dpi_hsync_pol(instance, !video_params->h_polarity);
\r
380 mipi_dsih_hal_dpi_vsync_pol(instance, !video_params->v_polarity);
\r
381 mipi_dsih_hal_dpi_dataen_pol(instance, !video_params->data_en_polarity);
\r
383 hs_timeout = ((video_params->h_total_pixels * video_params->v_active_lines) + (DSIH_PIXEL_TOLERANCE * bytes_per_pixel_x100) / 100);
\r
384 for (counter = 0x80; (counter < hs_timeout) && (counter > 2); counter--)
\r
386 if ((hs_timeout % counter) == 0)
\r
388 mipi_dsih_hal_timeout_clock_division(instance, counter);
\r
389 mipi_dsih_hal_lp_rx_timeout(instance, (uint16_t)(hs_timeout / counter));
\r
390 mipi_dsih_hal_hs_tx_timeout(instance, (uint16_t)(hs_timeout / counter));
\r
394 /* TX_ESC_CLOCK_DIV must be less than 20000KHz */
\r
395 mipi_dsih_hal_tx_escape_division(instance, 3); //6 //Jessica
\r
396 /* video packetisation */
\r
397 if (video_params->video_mode == VIDEO_BURST_WITH_SYNC_PULSES)
\r
399 mipi_dsih_hal_dpi_null_packet_en(instance, 0);
\r
400 mipi_dsih_hal_dpi_multi_packet_en(instance, 0);
\r
401 err_code = mipi_dsih_hal_dpi_null_packet_size(instance, 0);
\r
402 err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, 1);
\r
403 err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);
\r
404 if (err_code != OK)
\r
408 /* BURST by default, returns to LP during ALL empty periods - energy saving */
\r
409 mipi_dsih_hal_dpi_lp_during_hfp(instance, 1);
\r
410 mipi_dsih_hal_dpi_lp_during_hbp(instance, 1);
\r
411 mipi_dsih_hal_dpi_lp_during_vactive(instance, 1);
\r
412 mipi_dsih_hal_dpi_lp_during_vfp(instance, 1);
\r
413 mipi_dsih_hal_dpi_lp_during_vbp(instance, 1);
\r
414 mipi_dsih_hal_dpi_lp_during_vsync(instance, 1);
\r
417 if (instance->log_info != 0)
\r
419 instance->log_info("burst video");
\r
420 instance->log_info("h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
\r
421 instance->log_info("video_size %ld", video_size);
\r
426 { /* non burst transmission */
\r
427 null_packet_size = 0;
\r
428 /* bytes to be sent - first as one chunk*/
\r
429 bytes_per_chunk = (bytes_per_pixel_x100 * video_params->h_active_pixels) / 100 + VIDEO_PACKET_OVERHEAD;
\r
430 /* bytes being received through the DPI interface per byte clock cycle */
\r
431 total_bytes = (ratio_clock_xPF * video_params->no_of_lanes * (video_params->h_total_pixels - video_params->h_back_porch_pixels - video_params->h_sync_pixels)) / PRECISION_FACTOR;
\r
432 /* check if the in pixels actually fit on the DSI link */
\r
433 if (total_bytes >= bytes_per_chunk)
\r
435 chunk_overhead = total_bytes - bytes_per_chunk;
\r
436 /* overhead higher than 1 -> enable multi packets */
\r
437 if (chunk_overhead > 1)
\r
438 { /* MULTI packets */
\r
439 for (video_size = video_size_step; video_size < video_params->h_active_pixels; video_size += video_size_step)
\r
440 { /* determine no of chunks */
\r
441 if ((((video_params->h_active_pixels * PRECISION_FACTOR) / video_size) % PRECISION_FACTOR) == 0)
\r
443 no_of_chunks = video_params->h_active_pixels / video_size;
\r
444 bytes_per_chunk = (bytes_per_pixel_x100 * video_size) / 100 + VIDEO_PACKET_OVERHEAD;
\r
445 if (total_bytes >= (bytes_per_chunk * no_of_chunks))
\r
447 bytes_left = total_bytes - (bytes_per_chunk * no_of_chunks);
\r
452 /* prevent overflow (unsigned - unsigned) */
\r
453 if (bytes_left > (NULL_PACKET_OVERHEAD * no_of_chunks))
\r
455 null_packet_size = (bytes_left - (NULL_PACKET_OVERHEAD * no_of_chunks)) / no_of_chunks;
\r
456 if (null_packet_size > MAX_NULL_SIZE)
\r
457 { /* avoid register overflow */
\r
458 null_packet_size = MAX_NULL_SIZE;
\r
463 { /* no multi packets */
\r
467 if (instance->log_info != 0)
\r
469 instance->log_info("no multi no null video");
\r
470 instance->log_info("h line time %ld", (uint16_t)((video_params->h_total_pixels * ratio_clock_xPF) / PRECISION_FACTOR));
\r
471 instance->log_info("video_size %ld", video_size);
\r
473 /************************/
\r
475 /* video size must be a multiple of 4 when not 18 loosely */
\r
476 for (video_size = video_params->h_active_pixels; (video_size % video_size_step) != 0; video_size++)
\r
484 instance->log_error("resolution cannot be sent to display through current settings");
\r
485 err_code = ERR_DSI_OVERFLOW;
\r
488 err_code = err_code? err_code: mipi_dsih_hal_dpi_chunks_no(instance, no_of_chunks);
\r
489 err_code = err_code? err_code: mipi_dsih_hal_dpi_video_packet_size(instance, video_size);
\r
490 err_code = err_code? err_code: mipi_dsih_hal_dpi_null_packet_size(instance, null_packet_size);
\r
491 mipi_dsih_hal_dpi_null_packet_en(instance, null_packet_size > 0? 1: 0);
\r
492 mipi_dsih_hal_dpi_multi_packet_en(instance, (no_of_chunks > 1)? 1: 0);
\r
495 if (instance->log_info != 0)
\r
497 instance->log_info("total_bytes %d", total_bytes);
\r
498 instance->log_info("bytes_per_chunk %d", bytes_per_chunk);
\r
499 instance->log_info("bytes left %d", bytes_left);
\r
500 instance->log_info("null packets %d", null_packet_size);
\r
501 instance->log_info("chunks %ld", no_of_chunks);
\r
502 instance->log_info("video_size %ld", video_size);
\r
504 /************************/
\r
506 mipi_dsih_hal_dpi_video_vc(instance, video_params->virtual_channel);
\r
507 mipi_dsih_dphy_no_of_lanes(&(instance->phy_instance), video_params->no_of_lanes);
\r
508 /* enable high speed clock */
\r
509 mipi_dsih_dphy_enable_hs_clk(&(instance->phy_instance), 1);
\r
512 dsih_error_t mipi_dsih_dcs_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)
\r
514 uint8_t packet_type = 0;
\r
518 return ERR_DSI_OUT_OF_BOUND;
\r
520 if (param_length > 2)
\r
539 packet_type = 0x05; /* DCS short write no param */
\r
545 packet_type = 0x15; /* DCS short write 1 param */
\r
556 packet_type = 0x39; /* DCS long write/write_LUT command packet */
\r
559 if (instance->log_error != 0)
\r
561 instance->log_error("invalid DCS command");
\r
563 return ERR_DSI_INVALID_COMMAND;
\r
565 return mipi_dsih_gen_wr_packet(instance, vc, packet_type, params, param_length);
\r
567 void mipi_dsih_cmd_mode(dsih_ctrl_t * instance, int en)
\r
574 if (instance->status == INITIALIZED)
\r
576 if ((!mipi_dsih_hal_gen_is_cmd_mode(instance)) && en)
\r
577 { /* disable video mode first */
\r
578 mipi_dsih_hal_dpi_video_mode_en(instance, 0);
\r
579 mipi_dsih_hal_gen_cmd_mode_en(instance, 1);
\r
581 else if ((mipi_dsih_hal_gen_is_cmd_mode(instance)) && !en)
\r
583 mipi_dsih_hal_gen_cmd_mode_en(instance, 0);
\r
588 if (instance->log_error != 0)
\r
590 instance->log_error("invalid instance");
\r
593 void mipi_dsih_video_mode(dsih_ctrl_t * instance, int en)
\r
600 if (instance->status == INITIALIZED)
\r
602 if ((!mipi_dsih_hal_dpi_is_video_mode(instance)) && en)
\r
603 { /* disable cmd mode first */
\r
604 mipi_dsih_hal_gen_cmd_mode_en(instance, 0);
\r
605 mipi_dsih_hal_dpi_video_mode_en(instance, 1);
\r
607 else if ((!mipi_dsih_hal_dpi_is_video_mode(instance)) && !en)
\r
609 mipi_dsih_hal_dpi_video_mode_en(instance, 0);
\r
614 if (instance->log_error != 0)
\r
616 instance->log_error("invalid instance");
\r
619 int mipi_dsih_active_mode(dsih_ctrl_t * instance)
\r
621 if (mipi_dsih_hal_gen_is_cmd_mode(instance))
\r
625 else if (mipi_dsih_hal_dpi_is_video_mode(instance))
\r
631 dsih_error_t mipi_dsih_gen_wr_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length)
\r
633 uint8_t data_type = 0;
\r
634 switch(param_length)
\r
649 return mipi_dsih_gen_wr_packet(instance, vc, data_type, params, param_length);
\r
651 dsih_error_t mipi_dsih_gen_wr_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t* params, uint16_t param_length)
\r
653 dsih_error_t err_code = OK;
\r
654 /* active delay iterator */
\r
659 /* holds padding bytes needed */
\r
660 int compliment_counter = 0;
\r
661 uint8_t* payload = 0;
\r
662 /* temporary variable to arrange bytes into words */
\r
664 uint16_t word_count = 0;
\r
667 return ERR_DSI_INVALID_INSTANCE;
\r
669 if (instance->status != INITIALIZED)
\r
671 return ERR_DSI_INVALID_INSTANCE;
\r
673 if ((params == 0) && (param_length != 0)) /* pointer NULL */
\r
675 return ERR_DSI_OUT_OF_BOUND;
\r
677 if (param_length > 2)
\r
678 { /* long packet - write word count to header, and the rest to payload */
\r
679 payload = params + (2 * sizeof(params[0]));
\r
680 word_count = (params[1] << 8) | params[0];
\r
681 if ((param_length - 2) < word_count)
\r
683 if (instance->log_error != 0)
\r
685 instance->log_error("sent > input payload. complemented with zeroes");
\r
687 compliment_counter = (param_length - 2) - word_count;
\r
689 else if ((param_length - 2) > word_count)
\r
691 if (instance->log_error != 0)
\r
693 instance->log_error("Overflow - input > sent. payload truncated");
\r
696 for (i = 0; i < (param_length - 2); i += j)
\r
699 for (j = 0; (j < 4) && ((j + i) < (param_length - 2)); j++)
\r
700 { /* temp = (payload[i + 3] << 24) | (payload[i + 2] << 16) | (payload[i + 1] << 8) | payload[i]; */
\r
701 temp |= payload[i + j] << (j * 8);
\r
703 /* check if payload Tx fifo is not full */
\r
704 for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
\r
706 if (!mipi_dsih_hal_gen_packet_payload(instance, temp))
\r
711 if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
\r
713 return ERR_DSI_TIMEOUT;
\r
716 /* if word count entered by the user more than actual parameters received
\r
717 * fill with zeroes - a fail safe mechanism, otherwise controller will
\r
718 * want to send data from an empty buffer */
\r
719 for (i = 0; i < compliment_counter; i++)
\r
721 /* check if payload Tx fifo is not full */
\r
722 for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
\r
724 if (!mipi_dsih_hal_gen_packet_payload(instance, 0x00))
\r
729 if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
\r
731 return ERR_DSI_TIMEOUT;
\r
735 for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
\r
737 /* check if payload Tx fifo is not full */
\r
738 if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))
\r
740 if (param_length == 0)
\r
742 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, 0x0);
\r
744 else if (param_length == 1)
\r
746 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, 0x0, params[0]);
\r
750 err_code |= mipi_dsih_hal_gen_packet_header(instance, vc, data_type, params[1], params[0]);
\r
755 if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
\r
757 err_code = ERR_DSI_TIMEOUT;
\r
761 uint16_t mipi_dsih_dcs_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t command, uint8_t bytes_to_read, uint8_t* read_buffer)
\r
767 if (instance->status != INITIALIZED)
\r
787 /* COMMAND_TYPE 0x06 - DCS Read no params refer to DSI spec p.47 */
\r
788 return mipi_dsih_gen_rd_packet(instance, vc, 0x06, 0x0, command, bytes_to_read, read_buffer);
\r
790 if (instance->log_error != 0)
\r
792 instance->log_error("invalid DCS command");
\r
798 uint16_t mipi_dsih_gen_rd_cmd(dsih_ctrl_t * instance, uint8_t vc, uint8_t* params, uint16_t param_length, uint8_t bytes_to_read, uint8_t* read_buffer)
\r
800 uint8_t data_type = 0;
\r
805 if (instance->status != INITIALIZED)
\r
809 switch(param_length)
\r
813 return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, 0x00, bytes_to_read, read_buffer);
\r
816 return mipi_dsih_gen_rd_packet(instance, vc, data_type, 0x00, params[0], bytes_to_read, read_buffer);
\r
819 return mipi_dsih_gen_rd_packet(instance, vc, data_type, params[1], params[0], bytes_to_read, read_buffer);
\r
824 uint16_t mipi_dsih_gen_rd_packet(dsih_ctrl_t * instance, uint8_t vc, uint8_t data_type, uint8_t msb_byte, uint8_t lsb_byte, uint8_t bytes_to_read, uint8_t* read_buffer)
\r
826 dsih_error_t err_code = OK;
\r
830 int last_count = 0;
\r
831 uint32_t temp[1] = {0};
\r
836 if (instance->status != INITIALIZED)
\r
840 if (bytes_to_read < 1)
\r
844 if (read_buffer == 0)
\r
848 /* make sure command mode is on */
\r
849 mipi_dsih_cmd_mode(instance, 1);
\r
850 /* make sure receiving is enabled */
\r
851 mipi_dsih_hal_bta_en(instance, 1);
\r
852 /* listen to the same virtual channel as the one sent to */
\r
853 mipi_dsih_hal_gen_rd_vc(instance, vc);
\r
854 for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
\r
855 { /* check if payload Tx fifo is not full */
\r
856 if (!mipi_dsih_hal_gen_cmd_fifo_full(instance))
\r
858 mipi_dsih_hal_gen_packet_header(instance, vc, data_type, msb_byte, lsb_byte);
\r
862 if (!(timeout < DSIH_FIFO_ACTIVE_WAIT))
\r
864 if (instance->log_error != 0)
\r
866 instance->log_error("tx rd command timed out");
\r
870 /* loop for the number of words to be read */
\r
871 for (timeout = 0; timeout < DSIH_FIFO_ACTIVE_WAIT; timeout++)
\r
872 { /* check if command transaction is done */
\r
873 if (!mipi_dsih_hal_gen_rd_cmd_busy(instance))
\r
875 if (!mipi_dsih_hal_gen_read_fifo_empty(instance))
\r
877 for (counter = 0; (!mipi_dsih_hal_gen_read_fifo_empty(instance)); counter += 4)
\r
879 err_code = mipi_dsih_hal_gen_read_payload(instance, temp);
\r
884 if (counter < bytes_to_read)
\r
886 for (i = 0; i < 4; i++)
\r
888 if ((counter + i) < bytes_to_read)
\r
890 /* put 32 bit temp in 4 bytes of buffer passed by user*/
\r
891 read_buffer[counter + i] = (uint8_t)(temp[0] >> (i * 8));
\r
892 last_count = i + counter;
\r
896 if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)
\r
898 last_count = i + counter;
\r
905 last_count = counter;
\r
906 for (i = 0; i < 4; i++)
\r
908 if ((uint8_t)(temp[0] >> (i * 8)) != 0x00)
\r
910 last_count = i + counter;
\r
915 return last_count + 1;
\r
919 if (instance->log_error != 0)
\r
921 instance->log_error("rx buffer empty");
\r
927 if (instance->log_error != 0)
\r
929 instance->log_error("rx command timed out");
\r
933 uint32_t mipi_dsih_dump_register_configuration(dsih_ctrl_t * instance, int all, register_config_t *config, uint16_t config_length)
\r
935 uint32_t current = 0;
\r
936 uint16_t count = 0;
\r
939 return ERR_DSI_INVALID_INSTANCE;
\r
941 if (instance->status != INITIALIZED)
\r
943 return ERR_DSI_INVALID_INSTANCE;
\r
946 { /* dump all registers */
\r
947 for (current = R_DSI_HOST_VERSION; current <= R_DSI_HOST_ERROR_MSK1; count++, current += (R_DSI_HOST_PWR_UP - R_DSI_HOST_VERSION))
\r
949 if ((config_length == 0) || (config == 0) || count >= config_length)
\r
950 { /* no place to write - write to STD IO */
\r
951 if (instance->log_info != 0)
\r
953 instance->log_info("DSI 0x%lX:0x%lX", current, mipi_dsih_read_word(instance, current));
\r
958 config[count].addr = current;
\r
959 config[count].data = mipi_dsih_read_word(instance, current);
\r
967 if (instance->log_error != 0)
\r
969 instance->log_error("invalid buffer");
\r
974 for (count = 0; count < config_length; count++)
\r
976 config[count].data = mipi_dsih_read_word(instance, config[count].addr);
\r
982 uint32_t mipi_dsih_write_register_configuration(dsih_ctrl_t * instance, register_config_t *config, uint16_t config_length)
\r
984 uint16_t count = 0;
\r
987 return ERR_DSI_INVALID_INSTANCE;
\r
989 if (instance->status != INITIALIZED)
\r
991 return ERR_DSI_INVALID_INSTANCE;
\r
993 for (count = 0; count < config_length; count++)
\r
995 mipi_dsih_write_word(instance, config[count].addr, config[count].data);
\r
999 dsih_error_t mipi_dsih_register_event(dsih_ctrl_t * instance, dsih_event_t event, void (*handler)(dsih_ctrl_t *, void *))
\r
1001 uint32_t mask = 1;
\r
1002 uint32_t temp = 0;
\r
1003 if (event >= DSI_MAX_EVENT)
\r
1005 return ERR_DSI_INVALID_EVENT;
\r
1009 return ERR_DSI_INVALID_HANDLE;
\r
1011 if (instance == 0)
\r
1013 return ERR_DSI_INVALID_INSTANCE;
\r
1015 if (instance->status != INITIALIZED)
\r
1017 return ERR_DSI_INVALID_INSTANCE;
\r
1019 instance->event_registry[event] = handler;
\r
1020 if (event < HS_CONTENTION)
\r
1022 temp = mipi_dsih_hal_get_error_mask_0(instance, 0xffffffff);
\r
1023 temp &= ~(mask << event);
\r
1024 temp |= (0 & mask) << event;
\r
1025 mipi_dsih_hal_error_mask_0(instance, temp);
\r
1029 temp = mipi_dsih_hal_get_error_mask_1(instance, 0xffffffff);
\r
1030 temp &= ~(mask << (event - HS_CONTENTION));
\r
1031 temp |= (0 & mask) << (event - HS_CONTENTION);
\r
1032 mipi_dsih_hal_error_mask_1(instance, temp);
\r
1033 if (event == RX_CRC_ERR)
\r
1034 { /* automatically enable CRC reporting */
\r
1035 mipi_dsih_hal_gen_crc_rx_en(instance, 1);
\r
1040 dsih_error_t mipi_dsih_unregister_event(dsih_ctrl_t * instance, dsih_event_t event)
\r
1042 uint32_t mask = 1;
\r
1043 uint32_t temp = 0;
\r
1044 if (event >= DSI_MAX_EVENT)
\r
1046 return ERR_DSI_INVALID_EVENT;
\r
1048 if (instance == 0)
\r
1050 return ERR_DSI_INVALID_INSTANCE;
\r
1052 if (instance->status != INITIALIZED)
\r
1054 return ERR_DSI_INVALID_INSTANCE;
\r
1056 instance->event_registry[event] = 0;
\r
1057 if (event < HS_CONTENTION)
\r
1059 temp = mipi_dsih_hal_get_error_mask_0(instance, 0xffffffff);
\r
1060 temp &= ~(mask << event);
\r
1061 temp |= (1 & mask) << event;
\r
1062 mipi_dsih_hal_error_mask_0(instance, temp);
\r
1066 temp = mipi_dsih_hal_get_error_mask_1(instance, 0xffffffff);
\r
1067 temp &= ~(mask << (event - HS_CONTENTION));
\r
1068 temp |= (1 & mask) << (event - HS_CONTENTION);
\r
1069 mipi_dsih_hal_error_mask_1(instance, temp);
\r
1070 if (event == RX_CRC_ERR)
\r
1071 { /* automatically disable CRC reporting */
\r
1072 mipi_dsih_hal_gen_crc_rx_en(instance, 0);
\r
1077 dsih_error_t mipi_dsih_unregister_all_events(dsih_ctrl_t * instance)
\r
1080 if (instance == 0)
\r
1082 return ERR_DSI_INVALID_INSTANCE;
\r
1084 if (instance->status != INITIALIZED)
\r
1086 return ERR_DSI_INVALID_INSTANCE;
\r
1088 for (i = 0; i < DSI_MAX_EVENT; i++)
\r
1090 instance->event_registry[i] = 0;
\r
1092 mipi_dsih_hal_error_mask_0(instance, 0xffffff);
\r
1093 mipi_dsih_hal_error_mask_1(instance, 0xffffff);
\r
1094 /* automatically disable CRC reporting */
\r
1095 mipi_dsih_hal_gen_crc_rx_en(instance, 0);
\r
1098 void mipi_dsih_event_handler(void * param)
\r
1100 dsih_ctrl_t * instance = (dsih_ctrl_t *)(param);
\r
1102 uint32_t status_0;
\r
1103 uint32_t status_1;
\r
1104 if (instance == 0)
\r
1109 status_0 = mipi_dsih_hal_error_status_0(instance, 0xffffffff);
\r
1110 status_1 = mipi_dsih_hal_error_status_1(instance, 0xffffffff);
\r
1112 for (i = 0; i < DSI_MAX_EVENT; i++)
\r
1114 if (instance->event_registry[i] != 0)
\r
1116 if (i < HS_CONTENTION)
\r
1118 if ((status_0 & (1 << i)) != 0)
\r
1120 instance->event_registry[i](instance, &i);
\r
1125 if ((status_1 & (1 << (i - HS_CONTENTION))) != 0)
\r
1127 instance->event_registry[i](instance, &i);
\r
1133 void mipi_dsih_reset_controller(dsih_ctrl_t * instance)
\r
1135 mipi_dsih_hal_power(instance, 0);
\r
1136 mipi_dsih_hal_power(instance, 1);
\r
1138 void mipi_dsih_shutdown_controller(dsih_ctrl_t * instance, int shutdown)
\r
1140 mipi_dsih_hal_power(instance, !shutdown);
\r
1142 void mipi_dsih_reset_phy(dsih_ctrl_t * instance)
\r
1144 mipi_dsih_dphy_reset(&(instance->phy_instance), 0);
\r
1145 mipi_dsih_dphy_reset(&(instance->phy_instance), 1);
\r
1147 void mipi_dsih_shutdown_phy(dsih_ctrl_t * instance, int shutdown)
\r
1149 mipi_dsih_dphy_shutdown(&(instance->phy_instance), !shutdown);
\r