Am Samstag, 18. Juli 2026, 05:11:40 Mitteleuropäische Sommerzeit schrieb 
Jiaxing Hu:
> The RK3576 NPU domains need a short settle time after the idle
> request is released before the QoS registers behind the domain are
> written: restoring QoS immediately after de-idle can raise an SError
> on the register access while the NoC is still settling (observed on
> ROCK 4D as a panic inside rockchip_pd_power() during NPU runtime-PM
> cycling).
> 
> The vendor kernel handles this with a per-domain delay_us field
> applied between the de-idle request and the QoS restore, carrying
> 15us for the RK3576 NPUTOP domain.  Mirror that: add delay_us to
> rockchip_domain_info, honor it in rockchip_pd_power() right before
> rockchip_pmu_restore_qos(), and set 15us for NPUTOP, NPU0 and NPU1
> (the two core domains power-cycle constantly under runtime PM and
> showed the same symptom during bring-up).  All other domains keep 0,
> so nothing changes for them.
> 
> Signed-off-by: Jiaxing Hu <[email protected]>
> ---
>  drivers/pmdomain/rockchip/pm-domains.c | 51 ++++++++++++++------------
>  1 file changed, 28 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/pmdomain/rockchip/pm-domains.c 
> b/drivers/pmdomain/rockchip/pm-domains.c
> index 490bbb1d1..1787f62ba 100644
> --- a/drivers/pmdomain/rockchip/pm-domains.c
> +++ b/drivers/pmdomain/rockchip/pm-domains.c
> @@ -59,6 +59,7 @@ struct rockchip_domain_info {
>       u32 pwr_offset;
>       u32 mem_offset;
>       u32 req_offset;
> +     u32 delay_us;
>  };
>  
>  struct rockchip_pmu_info {
> @@ -185,7 +186,7 @@ struct rockchip_pmu {
>       .need_regulator = regulator,                    \
>  }
>  
> -#define DOMAIN_M_O_R_G(_name, p_offset, pwr, status, m_offset, m_status, 
> r_status, r_offset, req, idle, ack, g_mask, wakeup) \
> +#define DOMAIN_M_O_R_G(_name, p_offset, pwr, status, m_offset, m_status, 
> r_status, r_offset, req, idle, ack, g_mask, delay, wakeup)  \

DOMAIN_M_O_R_G describes the fields it sets (mask, offset,  regulator 
clk-ungate)

So if you're adding the new wakeup delay that is specific to this one
implementation-variant, please also add a _W the name DOMAIN_M_O_R_G_W


Otherwise looks good.


Heiko
>  {                                                    \
>       .name = _name,                                  \
>       .pwr_offset = p_offset,                         \
> @@ -200,6 +201,7 @@ struct rockchip_pmu {
>       .req_mask = (req),                              \
>       .idle_mask = (idle),                            \
>       .clk_ungate_mask = (g_mask),                    \
> +     .delay_us = (delay),                            \
>       .ack_mask = (ack),                              \
>       .active_wakeup = wakeup,                        \
>  }
> @@ -244,8 +246,8 @@ struct rockchip_pmu {
>  #define DOMAIN_RK3568(name, pwr, req, wakeup)                \
>       DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)
>  
> -#define DOMAIN_RK3576(name, p_offset, pwr, status, r_status, r_offset, req, 
> idle, g_mask, wakeup)    \
> -     DOMAIN_M_O_R_G(name, p_offset, pwr, status, 0, r_status, r_status, 
> r_offset, req, idle, idle, g_mask, wakeup)
> +#define DOMAIN_RK3576(name, p_offset, pwr, status, r_status, r_offset, req, 
> idle, g_mask, delay, wakeup)     \
> +     DOMAIN_M_O_R_G(name, p_offset, pwr, status, 0, r_status, r_status, 
> r_offset, req, idle, idle, g_mask, delay, wakeup)
>  
>  /*
>   * Dynamic Memory Controller may need to coordinate with us -- see
> @@ -612,7 +614,6 @@ static int rockchip_do_pmu_set_power_domain(struct 
> rockchip_pm_domain *pd,
>                       return ret;
>       }
>  
> -
>       ret = readx_poll_timeout_atomic(rockchip_pmu_domain_is_on, pd, is_on,
>                                       is_on == on, 0, 10000);
>       if (ret) {
> @@ -667,6 +668,9 @@ static int rockchip_pd_power(struct rockchip_pm_domain 
> *pd, bool power_on)
>               if (ret < 0)
>                       goto out;
>  
> +             if (pd->info->delay_us)
> +                     udelay(pd->info->delay_us);
> +
>               rockchip_pmu_restore_qos(pd);
>       }
>  
> @@ -1286,25 +1290,26 @@ static const struct rockchip_domain_info 
> rk3568_pm_domains[] = {
>  };
>  
>  static const struct rockchip_domain_info rk3576_pm_domains[] = {
> -     [RK3576_PD_NPU]         = DOMAIN_RK3576("npu",    0x0, BIT(0),  BIT(0), 
> 0,       0x0, 0,       0,       0,       false),
> -     [RK3576_PD_NVM]         = DOMAIN_RK3576("nvm",    0x0, BIT(6),  0,      
> BIT(6),  0x4, BIT(2),  BIT(18), BIT(2),  false),
> -     [RK3576_PD_SDGMAC]      = DOMAIN_RK3576("sdgmac", 0x0, BIT(7),  0,      
> BIT(7),  0x4, BIT(1),  BIT(17), 0x6,     false),
> -     [RK3576_PD_AUDIO]       = DOMAIN_RK3576("audio",  0x0, BIT(8),  0,      
> BIT(8),  0x4, BIT(0),  BIT(16), BIT(0),  false),
> -     [RK3576_PD_PHP]         = DOMAIN_RK3576("php",    0x0, BIT(9),  0,      
> BIT(9),  0x0, BIT(15), BIT(15), BIT(15), false),
> -     [RK3576_PD_SUBPHP]      = DOMAIN_RK3576("subphp", 0x0, BIT(10), 0,      
> BIT(10), 0x0, 0,       0,       0,       false),
> -     [RK3576_PD_VOP]         = DOMAIN_RK3576("vop",    0x0, BIT(11), 0,      
> BIT(11), 0x0, 0x6000,  0x6000,  0x6000,  false),
> -     [RK3576_PD_VO1]         = DOMAIN_RK3576("vo1",    0x0, BIT(14), 0,      
> BIT(14), 0x0, BIT(12), BIT(12), 0x7000,  false),
> -     [RK3576_PD_VO0]         = DOMAIN_RK3576("vo0",    0x0, BIT(15), 0,      
> BIT(15), 0x0, BIT(11), BIT(11), 0x6800,  false),
> -     [RK3576_PD_USB]         = DOMAIN_RK3576("usb",    0x4, BIT(0),  0,      
> BIT(16), 0x0, BIT(10), BIT(10), 0x6400,  true),
> -     [RK3576_PD_VI]          = DOMAIN_RK3576("vi",     0x4, BIT(1),  0,      
> BIT(17), 0x0, BIT(9),  BIT(9),  BIT(9),  false),
> -     [RK3576_PD_VEPU0]       = DOMAIN_RK3576("vepu0",  0x4, BIT(2),  0,      
> BIT(18), 0x0, BIT(7),  BIT(7),  0x280,   false),
> -     [RK3576_PD_VEPU1]       = DOMAIN_RK3576("vepu1",  0x4, BIT(3),  0,      
> BIT(19), 0x0, BIT(8),  BIT(8),  BIT(8),  false),
> -     [RK3576_PD_VDEC]        = DOMAIN_RK3576("vdec",   0x4, BIT(4),  0,      
> BIT(20), 0x0, BIT(6),  BIT(6),  BIT(6),  false),
> -     [RK3576_PD_VPU]         = DOMAIN_RK3576("vpu",    0x4, BIT(5),  0,      
> BIT(21), 0x0, BIT(5),  BIT(5),  BIT(5),  false),
> -     [RK3576_PD_NPUTOP]      = DOMAIN_RK3576("nputop", 0x4, BIT(6),  0,      
> BIT(22), 0x0, 0x18,    0x18,    0x18,    false),
> -     [RK3576_PD_NPU0]        = DOMAIN_RK3576("npu0",   0x4, BIT(7),  0,      
> BIT(23), 0x0, BIT(1),  BIT(1),  0x1a,    false),
> -     [RK3576_PD_NPU1]        = DOMAIN_RK3576("npu1",   0x4, BIT(8),  0,      
> BIT(24), 0x0, BIT(2),  BIT(2),  0x1c,    false),
> -     [RK3576_PD_GPU]         = DOMAIN_RK3576("gpu",    0x4, BIT(9),  0,      
> BIT(25), 0x0, BIT(0),  BIT(0),  BIT(0),  false),
> +     /*                                               name    p_offset pwr   
>    status  r_status r_offset req      idle     g_mask   delay wakeup */
> +     [RK3576_PD_NPU]         = DOMAIN_RK3576("npu",    0x0, BIT(0),  BIT(0), 
> 0,       0x0, 0,       0,       0,       0,    false),
> +     [RK3576_PD_NVM]         = DOMAIN_RK3576("nvm",    0x0, BIT(6),  0,      
> BIT(6),  0x4, BIT(2),  BIT(18), BIT(2),  0,    false),
> +     [RK3576_PD_SDGMAC]      = DOMAIN_RK3576("sdgmac", 0x0, BIT(7),  0,      
> BIT(7),  0x4, BIT(1),  BIT(17), 0x6,     0,    false),
> +     [RK3576_PD_AUDIO]       = DOMAIN_RK3576("audio",  0x0, BIT(8),  0,      
> BIT(8),  0x4, BIT(0),  BIT(16), BIT(0),  0,    false),
> +     [RK3576_PD_PHP]         = DOMAIN_RK3576("php",    0x0, BIT(9),  0,      
> BIT(9),  0x0, BIT(15), BIT(15), BIT(15), 0,    false),
> +     [RK3576_PD_SUBPHP]      = DOMAIN_RK3576("subphp", 0x0, BIT(10), 0,      
> BIT(10), 0x0, 0,       0,       0,       0,    false),
> +     [RK3576_PD_VOP]         = DOMAIN_RK3576("vop",    0x0, BIT(11), 0,      
> BIT(11), 0x0, 0x6000,  0x6000,  0x6000,  0,    false),
> +     [RK3576_PD_VO1]         = DOMAIN_RK3576("vo1",    0x0, BIT(14), 0,      
> BIT(14), 0x0, BIT(12), BIT(12), 0x7000,  0,    false),
> +     [RK3576_PD_VO0]         = DOMAIN_RK3576("vo0",    0x0, BIT(15), 0,      
> BIT(15), 0x0, BIT(11), BIT(11), 0x6800,  0,    false),
> +     [RK3576_PD_USB]         = DOMAIN_RK3576("usb",    0x4, BIT(0),  0,      
> BIT(16), 0x0, BIT(10), BIT(10), 0x6400,  0,    true),
> +     [RK3576_PD_VI]          = DOMAIN_RK3576("vi",     0x4, BIT(1),  0,      
> BIT(17), 0x0, BIT(9),  BIT(9),  BIT(9),  0,    false),
> +     [RK3576_PD_VEPU0]       = DOMAIN_RK3576("vepu0",  0x4, BIT(2),  0,      
> BIT(18), 0x0, BIT(7),  BIT(7),  0x280,   0,    false),
> +     [RK3576_PD_VEPU1]       = DOMAIN_RK3576("vepu1",  0x4, BIT(3),  0,      
> BIT(19), 0x0, BIT(8),  BIT(8),  BIT(8),  0,    false),
> +     [RK3576_PD_VDEC]        = DOMAIN_RK3576("vdec",   0x4, BIT(4),  0,      
> BIT(20), 0x0, BIT(6),  BIT(6),  BIT(6),  0,    false),
> +     [RK3576_PD_VPU]         = DOMAIN_RK3576("vpu",    0x4, BIT(5),  0,      
> BIT(21), 0x0, BIT(5),  BIT(5),  BIT(5),  0,    false),
> +     [RK3576_PD_NPUTOP]      = DOMAIN_RK3576("nputop", 0x4, BIT(6),  0,      
> BIT(22), 0x0, 0x18,    0x18,    0x18,    15,   false),
> +     [RK3576_PD_NPU0]        = DOMAIN_RK3576("npu0",   0x4, BIT(7),  0,      
> BIT(23), 0x0, BIT(1),  BIT(1),  0x1a,    15,   false),
> +     [RK3576_PD_NPU1]        = DOMAIN_RK3576("npu1",   0x4, BIT(8),  0,      
> BIT(24), 0x0, BIT(2),  BIT(2),  0x1c,    15,   false),
> +     [RK3576_PD_GPU]         = DOMAIN_RK3576("gpu",    0x4, BIT(9),  0,      
> BIT(25), 0x0, BIT(0),  BIT(0),  BIT(0),  0,    false),
>  };
>  
>  static const struct rockchip_domain_info rk3588_pm_domains[] = {
> 




Reply via email to