ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_mipi_dsi.c
Go to the documentation of this file.
1
63
64#include "ra8_mipi_dsi.h"
65
66#include <stddef.h>
67#include <stdint.h>
68#include <string.h>
69
70#include "ra8_attributes.h"
71#include "ra8_check.h"
72#include "ra8_err.h"
73#include "ra8_log.h"
75#include "ra8_mipi_dsi_regs.h"
76#include "ra8_mstp.h"
77
90static const char* s_tag = "MIPI_DSI";
91
107
122
138
154
164
181
196
223static bool s_initialized;
224
225/* =============================================================================
226 * Internal helpers
227 * =============================================================================
228 */
229
254
272{
273 volatile r_mipi_dsi_regs_t* reg = ra8_mipi_dsi();
274 /* HUM Ch 65.2 "SQCH0SCR : Sequence Channel 0 Status Clear", p 3902 */
276 /* HUM Ch 65.2 "SQCH1SCR : Sequence Channel 1 Status Clear", p 3907 */
278 /* HUM Ch 65.2 "VMSCR : Video Mode Status Clear", p 3894 */
280 /* HUM Ch 65.2 "RXSCR : Receive Status Clear", p 3855 */
282 /* HUM Ch 65.2 "FERRSCR : Fatal Error Status Clear", p 3878 */
284 /* HUM Ch 65.2 "PLSCR : PHY Lane Status Clear", p 3887 */
286}
287
311
328{
329 uint32_t v = ((uint32_t)cfg->max_return_packet_size & k_ra8_mipi_dsi_dsisetr_mrpsz_mask);
330 if (cfg->ecc_check_enable) {
332 }
333 if (cfg->eotp_enable) {
335 }
336 if (cfg->scramble_enable) {
338 }
339 if (cfg->tearing_detect_enable) {
341 }
342 v |= (((uint32_t)cfg->crc_check_vc_mask) << (uint32_t)k_dsisetr_vc_crc_shift) &
344 return v;
345}
346
349priv_ra8_mipi_dsi_internal_wait_eq(volatile const uint32_t* reg, uint32_t mask, uint32_t expect)
350{
351 for (uint32_t i = 0U; i < k_ra8_mipi_dsi_busy_loop_max; ++i) {
352 if ((*reg & mask) == expect) {
353 return k_ra8_ok;
354 }
355 }
357}
358
359/* =============================================================================
360 * Public API -- lifecycle
361 * =============================================================================
362 */
363
385{
386 volatile r_mipi_dsi_regs_t* reg = ra8_mipi_dsi();
387
388 /* HUM Ch 65.2 "RSTCR" p 3845 */ /* pulse SWRST. */
390 reg->RSTCR = 0U;
391
392 /* HUM Ch 65.2 "TXSETR" p 3842 */ /* / "ULPSSETR" p 3849 / "DSISETR" p 3855 */
394 reg->ULPSSETR = (uint32_t)cfg->ulps_wakeup_period << (uint32_t)k_ulpssetr_wkup_shift;
396
397 /* HUM Ch 65.2 "CLSTPTSETR" p 3881 */
398 reg->CLSTPTSETR =
405
406 /* HUM Ch 65.2 "LPTRNSTSETR" p 3883 */
408}
409
438
440{
441 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
443 RA8_RETURN_ON_ERROR(cfg_err, s_tag, "mipi_dsi_init: cfg invalid");
444
445 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 446 */
447 RA8_RETURN_ON_ERROR(mst_err, s_tag, "mipi_dsi_init: mstp enable");
448
452
454 s_clock_lanes_in_ulps = false;
455 s_data_lanes_in_ulps = false;
456 s_mipi_dsi_event_fn = nullptr;
457 s_mipi_dsi_event_ctx = nullptr;
460 s_initialized = true;
461
462 ra8_log_info(s_tag, "mipi_dsi_init done");
463 return k_ra8_ok;
464}
465
467{
468 /* Idempotent: a second deinit (or a deinit on a never-initialized
469 * driver) must succeed without underflowing the MSTPC refcount.
470 * HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 446. */
471 if (!s_initialized) {
472 return k_ra8_ok;
473 }
474
475 volatile r_mipi_dsi_regs_t* reg = ra8_mipi_dsi();
476 /* HUM Ch 65.2 "RSTCR : Reset Control Register", p 3845 */
478
479 s_mipi_dsi_event_fn = nullptr;
480 s_mipi_dsi_event_ctx = nullptr;
481 s_continuous_clock = false;
482 s_clock_lanes_in_ulps = false;
483 s_data_lanes_in_ulps = false;
486
487 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 446 */
489 if (err == k_ra8_ok) {
490 s_initialized = false;
491 }
492 return err;
493}
494
496{
497 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 446.
498 * Releases the MSTPC reference taken in ``init``; the matching
499 * ``exit_stop`` re-acquires it. */
500 if (!s_initialized) {
502 }
504 if (err == k_ra8_ok) {
505 s_initialized = false;
506 }
507 return err;
508}
509
511{
512 /* HUM Ch 11.2.8 "MSTPCRC : Module Stop Control Register C", p 446.
513 * Re-acquires the MSTPC reference released by ``enter_stop``. */
514 if (s_initialized) {
516 }
518 if (err == k_ra8_ok) {
519 s_initialized = true;
520 }
521 return err;
522}
523
525{
526 volatile r_mipi_dsi_regs_t* reg = ra8_mipi_dsi();
527 /* HUM Ch 65.2 "RSTCR : Reset Control Register", p 3845 */
529 /* HUM Ch 65.2 "RSTCR : Reset Control Register", p 3845 */
530 reg->RSTCR = 0U;
531 return k_ra8_ok;
532}
533
534/* =============================================================================
535 * HS clock control
536 * =============================================================================
537 */
538
540{
541 volatile r_mipi_dsi_regs_t* reg = ra8_mipi_dsi();
542 uint32_t hsclk = k_ra8_mipi_dsi_hsclk_start;
543 if (s_continuous_clock) {
545 }
546 /* HUM Ch 65.2 "HSCLKSETR : HS Clock Setting Register", p 3843 */
547 reg->HSCLKSETR = hsclk;
548 /* HUM Ch 65.2 "PLSR : PHY Lane Status Register", p 3884 */
552}
553
555{
556 volatile r_mipi_dsi_regs_t* reg = ra8_mipi_dsi();
557 /* HUM Ch 65.2 "HSCLKSETR : HS Clock Setting Register", p 3843 */
558 reg->HSCLKSETR = 0U;
559 /* HUM Ch 65.2 "PLSR : PHY Lane Status Register", p 3884 */
563}
564
565/* =============================================================================
566 * ULPS
567 * =============================================================================
568 */
569
570[[nodiscard]] ra8_err_t ra8_mipi_dsi_ulps_enter(uint8_t lanes)
571{
572 if (lanes == k_ra8_mipi_dsi_lane_none) {
574 }
575 /* Continuous clock mode forbids clock-lane ULPS -- HUM Ch 65 lists
576 * this constraint and FSP enforces the same precondition. */
577 if (((lanes & k_ra8_mipi_dsi_lane_clock) != 0U) && s_continuous_clock) {
578 ra8_log_error(s_tag, "ulps_enter: clock lane + continuous mode rejected");
580 }
581 uint32_t ulpscr = 0U;
582 if (((lanes & k_ra8_mipi_dsi_lane_data) != 0U) && !s_data_lanes_in_ulps) {
585 }
586 if (((lanes & k_ra8_mipi_dsi_lane_clock) != 0U) && !s_clock_lanes_in_ulps) {
589 }
590 /* HUM Ch 65.2 "ULPSCR : ULPS Control Register", p 3844 */
591 ra8_mipi_dsi()->ULPSCR = ulpscr;
592 return k_ra8_ok;
593}
594
595[[nodiscard]] ra8_err_t ra8_mipi_dsi_ulps_exit(uint8_t lanes)
596{
597 if (lanes == k_ra8_mipi_dsi_lane_none) {
599 }
600 uint32_t ulpscr = 0U;
601 if (((lanes & k_ra8_mipi_dsi_lane_data) != 0U) && s_data_lanes_in_ulps) {
603 s_data_lanes_in_ulps = false;
604 }
605 if (((lanes & k_ra8_mipi_dsi_lane_clock) != 0U) && s_clock_lanes_in_ulps) {
607 s_clock_lanes_in_ulps = false;
608 }
609 /* HUM Ch 65.2 "ULPSCR : ULPS Control Register", p 3844 */
610 ra8_mipi_dsi()->ULPSCR = ulpscr;
611 return k_ra8_ok;
612}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
static bool s_initialized
True once display_init has succeeded.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
ra8_err_t ra8_mipi_dsi_exit_stop(void)
Re-enable the MIPI DSI block clock from MSTP.
ra8_err_t ra8_mipi_dsi_deinit(void)
Tear down the MIPI DSI host link layer.
static void internal_program_timeouts(const ra8_mipi_dsi_config_t *cfg)
Program the peripheral-response and transmit-side timeouts.
ra8_err_t ra8_mipi_dsi_soft_reset(void)
Pulse RSTCR.SWRST to take the protocol-layer state back to a clean slate (registers retained).
ra8_err_t ra8_mipi_dsi_hs_clock_start(void)
Start the high-speed differential clock to the panel.
static bool s_continuous_clock
Cache of cfg->clock_mode == continuous from the last init.
static uint32_t internal_ra8_mipi_dsi_make_dsisetr(const ra8_mipi_dsi_config_t *cfg)
Compose DSISETR from a config.
ra8_err_t ra8_mipi_dsi_ulps_exit(uint8_t lanes)
Wake the selected lanes out of ULPS.
void * s_mipi_dsi_event_ctx
Single definition of the shared IRQ callback context.
uint16_t s_mipi_dsi_pending_rx_len
Single definition of the shared pending receive capacity.
static void internal_program_link(const ra8_mipi_dsi_config_t *cfg)
Pulse the RSTCR software reset and program the steady-state link-level registers.
ra8_err_t priv_ra8_mipi_dsi_internal_wait_eq(volatile const uint32_t *reg, uint32_t mask, uint32_t expect)
Implementation of priv_ra8_mipi_dsi_internal_wait_eq() – bounded busy-poll.
ra8_err_t ra8_mipi_dsi_init(const ra8_mipi_dsi_config_t *cfg)
Bring up the MIPI DSI host link layer.
ra8_mipi_dsi_event_fn_t s_mipi_dsi_event_fn
Single definition of the shared IRQ callback pointer.
static bool s_clock_lanes_in_ulps
Software shadow of clock-lane ULPS state.
static ra8_err_t internal_ra8_mipi_dsi_validate_cfg(const ra8_mipi_dsi_config_t *cfg)
Validate a ra8_mipi_dsi_config_t argument.
static void internal_ra8_mipi_dsi_clear_all_status(void)
Clear every latched status bit in every sub-status register.
ra8_err_t ra8_mipi_dsi_enter_stop(void)
Gate the MIPI DSI block at the MSTP register.
ra8_err_t ra8_mipi_dsi_ulps_enter(uint8_t lanes)
Drive the selected lanes into Ultra-Low-Power State.
ra8_err_t ra8_mipi_dsi_hs_clock_stop(void)
Stop the high-speed differential clock.
uint8_t * s_mipi_dsi_pending_rx_buffer
Single definition of the shared pending receive buffer.
static uint32_t internal_ra8_mipi_dsi_make_txsetr(const ra8_mipi_dsi_config_t *cfg)
Compose TXSETR from a config (lane count + clock + data lane enable).
static bool s_data_lanes_in_ulps
Software shadow of data-lane ULPS state.
MIPI DSI-2 host driver – public API (full HUM Ch 65 surface).
Module-private link seam shared between the MIPI DSI-2 hostdriver translation units.
@ k_dsisetr_vc_crc_shift
Dsisetr vc CRC shift.
@ k_ulpssetr_wkup_shift
Ulpssetr wkup shift.
MIPI DSI Host (DSI-2) register layout for the RA8D2.
@ k_ra8_mipi_dsi_vmsr_clear_all
Mask of every defined VMSR bit – write to VMSCR to scrub.
@ k_ra8_mipi_dsi_hsclk_start
HSCLST: HS clock start.
@ k_ra8_mipi_dsi_hsclk_continuous
HSCLMD: continuous mode.
@ k_ra8_mipi_dsi_rstcr_swrst
Assert software reset.
@ k_ra8_mipi_dsi_busy_loop_max
Max iterations per wait.
@ k_ra8_mipi_dsi_ferrsr_clear_all
RW1C-able fields in FERRSCR (status-only bits 27/28 excluded).
@ k_ra8_mipi_dsi_txset_lane2
NUMLANE = 1: 2 data lanes.
@ k_ra8_mipi_dsi_txset_dlen
DLEN: data-lane enable.
@ k_ra8_mipi_dsi_txset_clen
CLEN: clock-lane enable.
static volatile r_mipi_dsi_regs_t * ra8_mipi_dsi(void)
Pointer to the RA8D2 MIPI DSI host register block.
@ k_ra8_mipi_dsi_clstpt_clkkpt_shift
CLKKPT pos.
@ k_ra8_mipi_dsi_clstpt_clkstpt_shift
CLKSTPT pos.
@ k_ra8_mipi_dsi_clstpt_clkstpt_mask
CLKSTPT[11:2].
@ k_ra8_mipi_dsi_clstpt_clkkpt_mask
CLKKPT[31:24] mask, sets the HS-to-LP clock keep time.
@ k_ra8_mipi_dsi_clstpt_clkbfht_mask
CLKBFHT[23:16] mask, sets the LP-to-HS clock guard time.
@ k_ra8_mipi_dsi_clstpt_clkbfht_shift
CLKBFHT pos.
@ k_ra8_mipi_dsi_lptrnst_golpbkt_mask
GOLPBKT[9:0].
@ k_ra8_mipi_dsi_ulpscr_dlexit
Data-lane ULPS exit.
@ k_ra8_mipi_dsi_ulpscr_dlent
Data-lane ULPS enter.
@ k_ra8_mipi_dsi_ulpscr_clexit
Clock-lane ULPS exit.
@ k_ra8_mipi_dsi_ulpscr_clent
Clock-lane ULPS enter.
@ k_ra8_mipi_dsi_rxsr_clear_all
Mask of every defined RXSR bit – write to RXSCR to scrub.
@ k_ra8_mipi_dsi_plsr_clhs2lp
CL HS-to-LP transition.
@ k_ra8_mipi_dsi_plsr_cllp2hs
CL LP-to-HS transition.
@ k_ra8_mipi_dsi_plsr_clear_all
Bit subset that is RW1C in PLSCR (steady-state lane bits aren't).
@ k_ra8_mipi_dsi_sqch_clear_all
Mask of every RW1C bit in SQCH*SCR.
@ k_ra8_mipi_dsi_dsisetr_extemd
External tearing detect.
@ k_ra8_mipi_dsi_dsisetr_vc_crc_mask
Mask for the four per-VC CRC enable bits.
@ k_ra8_mipi_dsi_dsisetr_mrpsz_mask
MRPSZ field mask.
@ k_ra8_mipi_dsi_dsisetr_eccen
ECC check enable.
@ k_ra8_mipi_dsi_dsisetr_scren
Data scramble enable.
@ k_ra8_mipi_dsi_dsisetr_eotpen
HS Tx EoTp enable.
@ k_ra8_mipi_dsi_clock_continuous
HS clock runs forever.
@ k_ra8_mipi_dsi_lane_data
All data lanes (1 or 2).
@ k_ra8_mipi_dsi_lane_none
No lanes selected.
@ k_ra8_mipi_dsi_lane_clock
Clock lane.
@ k_ra8_mipi_dsi_lanes_1
1 data lane + 1 clock lane.
@ k_ra8_mipi_dsi_lanes_2
2 data lanes + 1 clock lane.
void(* ra8_mipi_dsi_event_fn_t)(void *ctx, ra8_mipi_dsi_event_t event, uint32_t status_mask)
MIPI DSI ISR-context callback signature.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
@ k_ra8_mstp_mipi_dsi
MSTPC10 MIPI DSI.
MIPI DSI host register block (full layout).
volatile uint32_t RSTCR
+0x110 Software reset control.
volatile uint32_t DSISETR
+0x120 DSI link configuration.
volatile uint32_t CLSTPTSETR
+0x314 Clock-lane stop time.
volatile uint32_t TATOSETR
+0x2E8 Turnaround ack timeout.
volatile uint32_t LPTRNSTSETR
+0x318 LP transition time.
volatile uint32_t VMSCR
+0x414 Video-mode status clear.
volatile uint32_t TXSETR
+0x100 Lane enable + count.
volatile uint32_t SQCH0SCR
+0x5D4 Sequence ch 0 clear.
volatile uint32_t PRESPTOHSSETR
+0x218 Peripheral resp TO (HS).
volatile uint32_t RXSCR
+0x204 Receive status clear.
volatile uint32_t PLSR
+0x320 PHY (PPI) status (RO).
volatile uint32_t ULPSCR
+0x10C ULPS enter/exit pulses.
volatile uint32_t LRXHTOSETR
+0x2E4 LP-RX host timeout.
volatile uint32_t HSTXTOSETR
+0x2E0 HS Tx timeout count.
volatile uint32_t ULPSSETR
+0x108 ULPS wakeup period.
volatile uint32_t SQCH1SCR
+0x614 Sequence ch 1 clear.
volatile uint32_t HSCLKSETR
+0x104 HS clock control.
volatile uint32_t PLSCR
+0x324 PHY status clear.
volatile uint32_t PRESPTOLPSETR
+0x214 Peripheral resp TO (LP).
volatile uint32_t FERRSCR
+0x304 Fatal-error status clear.
volatile uint32_t PRESPTOBTASETR
+0x210 Peripheral resp TO (BTA).
Static configuration passed to ra8_mipi_dsi_init.
uint16_t max_return_packet_size
DSISETR.MRPSZ.
ra8_mipi_dsi_timeouts_t timeouts
Bus timeouts.
uint8_t crc_check_vc_mask
Bit i = VCi CRC.
ra8_mipi_dsi_timing_t timing
Guard timings.
bool ecc_check_enable
DSISETR.ECCEN.
ra8_mipi_dsi_clock_mode_t clock_mode
HS clock mode.
ra8_mipi_dsi_lane_count_t lane_count
1 or 2.
bool scramble_enable
DSISETR.SCREN.
uint8_t ulps_wakeup_period
ULPSSETR.WKUP.
bool eotp_enable
DSISETR.EOTPEN.
bool tearing_detect_enable
DSISETR.EXTEMD.
uint32_t lp_rx_host_timeout
LRXHTOSETR.
uint32_t turnaround_timeout
TATOSETR.
uint32_t hs_tx_timeout
HSTXTOSETR.
uint32_t hs_rw_timeout
PRESPTOHSSETR (split HSRTO|HSWTO).
uint32_t bta_timeout
PRESPTOBTASETR.
uint32_t lp_rw_timeout
PRESPTOLPSETR (split LPRTO|LPWTO).
uint16_t go_lp_and_back
LPTRNSTSETR.GOLPBKT[9:0].
uint8_t clock_beforehand_time
CLSTPTSETR.CLKBFHT[23:16].
uint16_t clock_stop_time
CLSTPTSETR.CLKSTPT[11:2].
uint8_t clock_keep_time
CLSTPTSETR.CLKKPT[31:24].