ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_lpm_graphics.c File Reference

Graphics power-domain bring-up for the LPM HAL driver. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
#include "ra8_lpm.h"
#include "ra8_lpm_regs.h"
#include "ra8_register_protection.h"
Include dependency graph for ra8_lpm_graphics.c:

Go to the source code of this file.

Functions

static ra8_err_t internal_pdctrgd_wait (uint8_t mask, bool want_set, uint32_t limit)
 Poll a PDCTRGD status flag until it reads the wanted level.
static void internal_graphics_enable_moco (void)
 Start MOCO so the graphics power-gating controller has a clock.
static ra8_err_t internal_graphics_confirm_ready (uint32_t limit)
 Wait until PDCSF = 0 and PDPGSF = 1 (domain ready for the clear).
static ra8_err_t internal_graphics_confirm_powered (uint32_t limit)
 Wait until PDCSF = 0 and PDPGSF = 0 (gating finished, domain live).
static void internal_graphics_clear_pdde (void)
 Clear PDDE under the PRC1 unlock so the domain powers on.
ra8_err_t ra8_lpm_graphics_power_on (uint32_t timeout_iters)
 Power the graphics domain on (DRW / GLCDC / MIPI DSI+CSI / VIN).

Variables

static const char * s_tag = "LPM"
 Component tag used in every log line emitted by this driver.

Detailed Description

Graphics power-domain bring-up for the LPM HAL driver.

Tag
[Ring 3 / HAL] {World: S}

Implements ra8_lpm_graphics_power_on (declared in ra8_lpm.h) and its static helpers. Split out of ra8_lpm.c so neither translation unit exceeds the file-size cap: the graphics power-gating sequence is a distinct responsibility from the sleep-mode / clock-shutdown matrix that remains in the core driver.

The sequence follows HUM Ch 11.5.1 (p 480) and HUM Ch 11.2.14 (PDCTRGD, p 452): start MOCO (MOCOCR is PRC0/CGC), wait for the controller to become ready, clear PDCTRGD.PDDE under the PRC1 unlock to request power-on, then confirm the domain is live. Every protected write runs inside a scoped RA8_PROTECTED_WRITE window so it cannot be silently discarded.

Definition in file ra8_lpm_graphics.c.

Function Documentation

◆ internal_graphics_clear_pdde()

void internal_graphics_clear_pdde ( void )
static

Clear PDDE under the PRC1 unlock so the domain powers on.

PDCTRGD is PRC1-protected (HUM Ch 13.1 Table 13.1 p 521); without the unlock the clear is dropped. PDDE = 0 powers the domain ON.

Precondition
The domain was confirmed ready by internal_graphics_confirm_ready.
Single-threaded init context or interrupts masked.
Postcondition
PDCTRGD.PDDE is 0 (power-on requested).
PRCR is re-locked on exit.
Note
Not thread-safe.
Since
0.1.0

Definition at line 162 of file ra8_lpm_graphics.c.

References k_ra8_lpm_pdctrgd_off, k_ra8_prcr_unlock_lpm, RA8_INTERNAL, ra8_lpm_sysc_reg8(), and RA8_PROTECTED_WRITE.

Referenced by ra8_lpm_graphics_power_on().

◆ internal_graphics_confirm_powered()

ra8_err_t internal_graphics_confirm_powered ( uint32_t limit)
static

Wait until PDCSF = 0 and PDPGSF = 0 (gating finished, domain live).

Gating is complete when the controller is idle and the domain is no longer gated; split out of ra8_lpm_graphics_power_on for size.

Parameters
[in]limitIteration bound handed to internal_pdctrgd_wait.
Returns
k_ra8_ok when both flags reached their level.
Return values
k_ra8_okPDCSF == 0 and PDPGSF == 0 within limit polls.
k_ra8_err_hw_timeoutA flag never settled.
Precondition
limit > 0.
internal_graphics_clear_pdde has requested power-on.
Postcondition
No register is written.
The return value reflects the first flag that failed to settle.
Note
Not thread-safe.
Since
0.1.0

Definition at line 140 of file ra8_lpm_graphics.c.

References internal_pdctrgd_wait(), k_ra8_lpm_pdctr_pdcsf_mask, k_ra8_lpm_pdctr_pdpgsf_mask, RA8_INTERNAL, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ra8_lpm_graphics_power_on().

◆ internal_graphics_confirm_ready()

ra8_err_t internal_graphics_confirm_ready ( uint32_t limit)
static

Wait until PDCSF = 0 and PDPGSF = 1 (domain ready for the clear).

HUM Ch 11.2.14 p 452 gates the PDDE clear on PDCSF = 0 then PDPGSF = 1; split out of ra8_lpm_graphics_power_on for size.

Parameters
[in]limitIteration bound handed to internal_pdctrgd_wait.
Returns
k_ra8_ok when both flags reached their level.
Return values
k_ra8_okPDCSF == 0 and PDPGSF == 1 within limit polls.
k_ra8_err_hw_timeoutA flag never settled.
Precondition
limit > 0.
The controller is quiescent enough to make progress.
Postcondition
No register is written.
The return value reflects the first flag that failed to settle.
Note
Not thread-safe.
Since
0.1.0

Definition at line 116 of file ra8_lpm_graphics.c.

References internal_pdctrgd_wait(), k_ra8_lpm_pdctr_pdcsf_mask, k_ra8_lpm_pdctr_pdpgsf_mask, RA8_INTERNAL, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ra8_lpm_graphics_power_on().

◆ internal_graphics_enable_moco()

void internal_graphics_enable_moco ( void )
static

Start MOCO so the graphics power-gating controller has a clock.

HUM Ch 11.5.1 p 480 requires MOCOCR.MCSTP = 0 before power gating; MOCOCR is PRC0 (CGC) so the clear runs in a CGC unlock window.

Precondition
Called on the power-on path with the domain still gated.
Single-threaded init context or interrupts masked.
Postcondition
MOCOCR.MCSTP is 0 (MOCO running).
PRCR is re-locked on exit.
Note
Not thread-safe.
Since
0.1.0

Definition at line 90 of file ra8_lpm_graphics.c.

References k_ra8_lpm_clock_stop_mask, k_ra8_lpm_mococr_off, k_ra8_prcr_unlock_cgc, RA8_INTERNAL, ra8_lpm_sysc_reg8(), and RA8_PROTECTED_WRITE.

Referenced by ra8_lpm_graphics_power_on().

◆ internal_pdctrgd_wait()

ra8_err_t internal_pdctrgd_wait ( uint8_t mask,
bool want_set,
uint32_t limit )
static

Poll a PDCTRGD status flag until it reads the wanted level.

Busy-polls the read-only graphics power-domain status register for at most limit iterations (NASA Rule 2 bound); no PRCR window is needed.

Parameters
[in]maskk_ra8_lpm_pdctr_*_mask bit to watch.
[in]want_settrue to wait for set, false for clear.
[in]limitIteration bound (NASA Rule 2).
Returns
k_ra8_ok if the flag reached the level, else timeout.
Return values
k_ra8_okThe watched bit read want_set within limit polls.
k_ra8_err_hw_timeoutThe bit never reached want_set.
Precondition
limit > 0.
mask names exactly one PDCTRGD bit.
Postcondition
No register is written.
At most limit reads of PDCTRGD were issued.
Note
Not thread-safe.
Since
0.1.0

Definition at line 66 of file ra8_lpm_graphics.c.

References k_ra8_err_hw_timeout, k_ra8_lpm_pdctrgd_off, k_ra8_ok, RA8_INTERNAL, and ra8_lpm_sysc_reg8().

Referenced by internal_graphics_confirm_powered(), and internal_graphics_confirm_ready().

◆ ra8_lpm_graphics_power_on()

ra8_err_t ra8_lpm_graphics_power_on ( uint32_t timeout_iters)
nodiscard

Power the graphics domain on (DRW / GLCDC / MIPI DSI+CSI / VIN).

Clears PDCTRGD.PDDE so the graphics power domain leaves its gated reset state, then waits for the controller to report the transition complete. HUM Ch 11.5.1 Table 11.7 p 480 lists the domain contents: MIPI DSI, MIPI CSI, VIN, DRW and GLCDC. HUM Ch 11.2.14 p 452 gives the register a reset value of 0x81PDPGSF = 1 (gated off) and PDDE = 1 (power off) – so every one of those peripherals is unpowered out of reset and cancelling module-stop alone is not enough to make one respond.

This was the whole of issue #247: the D/AVE 2D engine had never rasterised a pixel on real silicon because nothing ever powered its domain. Bench evidence on an EK-RA8D2 – with PDCTRGD at its 0x81 reset value the DRW HWREVISION register reads 0x00000000; after this call it reads 0x0FBE0107.

Sequence (HUM Ch 11.2.14 p 452 + Ch 11.5.1 p 480):

  1. MOCO must already be running – "when using the power gating function, it should be set MOCOCR.MCSTP to 0 (MOCO is operated) in advance". The call starts MOCO itself so the caller cannot forget.
  2. ``PDDE`` may be moved 1 -> 0 only "after confirmed that the PDCSF = 0 and PDPGSF = 1", so both flags are polled first.
  3. Clear PDDE (the register is PRC1-protected, so the write runs inside an RA8_PROTECTED_WRITE window).
  4. Wait for PDCSF = 0 and PDPGSF = 0 – gating finished, the domain is live.

Idempotent: if the domain is already powered (PDPGSF = 0) the function returns k_ra8_ok without touching the register, so several graphics drivers may each call it during their own init.

Parameters
[in]timeout_itersPoll-loop bound for each flag wait; must be non-zero. Bounds the loop for NASA Rule 2.
Returns
ra8_err_t error code.
Return values
k_ra8_okDomain powered and gating complete.
k_ra8_err_invalid_argtimeout_iters was 0.
k_ra8_err_hw_timeoutA status flag never reached its target state within timeout_iters.
Precondition
timeout_iters > 0.
Single-threaded init context (the polls block the CPU).
Postcondition
On success PDCTRGD.PDPGSF == 0 and PDCTRGD.PDCSF == 0.
On success MOCO is running (MOCOCR.MCSTP == 0).
Note
Thread safety: not thread-safe.
Must run before any DRW / GLCDC / MIPI / VIN register access; reads of an unpowered domain return 0 and writes are lost.
Example:
(void)ra8_drw_init(&drw_cfg);
ra8_err_t ra8_drw_init(const ra8_drw_config_t *cfg)
Power on the DRW block, install the supplied configuration, and arm the IRQ control register.
Definition ra8_drw.c:491
@ k_ra8_lpm_pd_timeout_default
Default power-gate poll bound.
Definition ra8_lpm.h:145
ra8_err_t ra8_lpm_graphics_power_on(uint32_t timeout_iters)
Power the graphics domain on (DRW / GLCDC / MIPI DSI+CSI / VIN).
See also
ra8_lpm_set_clock_stop() Starts the MOCO this call depends on
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: both poll loops bounded by timeout_iters.
  • Rule 5: 1 precondition check + 2 postcondition polls.

Definition at line 171 of file ra8_lpm_graphics.c.

References internal_graphics_clear_pdde(), internal_graphics_confirm_powered(), internal_graphics_confirm_ready(), internal_graphics_enable_moco(), k_ra8_err_invalid_arg, k_ra8_lpm_pdctr_pdpgsf_mask, k_ra8_lpm_pdctrgd_off, k_ra8_ok, ra8_log_error, ra8_log_info, ra8_lpm_sysc_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ra8_drw_init().

Variable Documentation

◆ s_tag

const char* s_tag = "LPM"
static

Component tag used in every log line emitted by this driver.

Definition at line 39 of file ra8_lpm_graphics.c.