mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
media: iris: vpu3x: Add MNoC low power handshake during hardware power-off
Add the missing write to AON_WRAPPER_MVP_NOC_LPI_CONTROL before
reading the LPI status register. Introduce a handshake loop to ensure
MNoC enters low power mode reliably during VPU3 hardware power-off with
timeout handling.
Fixes: 02083a1e00 ("media: platform: qcom/iris: add support for vpu33")
Cc: stable@vger.kernel.org
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
parent
fde38008fc
commit
93fad55aa9
|
|
@ -19,6 +19,9 @@
|
|||
#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
|
||||
#define REQ_POWER_DOWN_PREP BIT(0)
|
||||
#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
|
||||
#define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */
|
||||
#define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */
|
||||
#define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */
|
||||
#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
|
||||
#define CORE_CLK_RUN 0x0
|
||||
|
||||
|
|
@ -109,7 +112,9 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core)
|
|||
|
||||
static void iris_vpu33_power_off_hardware(struct iris_core *core)
|
||||
{
|
||||
bool handshake_done = false, handshake_busy = false;
|
||||
u32 reg_val = 0, value, i;
|
||||
u32 count = 0;
|
||||
int ret;
|
||||
|
||||
if (iris_vpu3x_hw_power_collapsed(core))
|
||||
|
|
@ -128,13 +133,36 @@ static void iris_vpu33_power_off_hardware(struct iris_core *core)
|
|||
goto disable_power;
|
||||
}
|
||||
|
||||
/* Retry up to 1000 times as recommended by hardware documentation */
|
||||
do {
|
||||
/* set MNoC to low power */
|
||||
writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
|
||||
|
||||
udelay(15);
|
||||
|
||||
value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
|
||||
|
||||
handshake_done = value & NOC_LPI_STATUS_DONE;
|
||||
handshake_busy = value & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE);
|
||||
|
||||
if (handshake_done || !handshake_busy)
|
||||
break;
|
||||
|
||||
writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
|
||||
|
||||
udelay(15);
|
||||
|
||||
} while (++count < 1000);
|
||||
|
||||
if (!handshake_done && handshake_busy)
|
||||
dev_err(core->dev, "LPI handshake timeout\n");
|
||||
|
||||
ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS,
|
||||
reg_val, reg_val & BIT(0), 200, 2000);
|
||||
if (ret)
|
||||
goto disable_power;
|
||||
|
||||
/* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
|
||||
writel(BIT(0), core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
|
||||
writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
|
||||
|
||||
writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
|
||||
core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user