mirror of https://github.com/torvalds/linux.git
pmdomain core:
- Allow power-off for out-of-band wakeup-capable devices - Drop the redundant call to dev_pm_domain_detach() for the amba bus - Extend the genpd governor for CPUs to account for IPIs pmdomain providers: - bcm: Add support for BCM2712 - mediatek: Add support for MFlexGraphics power domains - mediatek: Add support for MT8196 power domains - qcom: Add RPMh power domain support for Kaanapali - rockchip: Add support for RV1126B pmdomain consumers: - usb: dwc3: Enable out of band wakeup for i.MX95 - usb: chipidea: Enable out of band wakeup for i.MX95 -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmkt1HYXHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCk3PQ//W24ZdZ5cqXJASrw4YihTovbR Pk/cVBacua32r3uBAf+GKdhAXrC7zaPbohp4tou5tpuY6I54NDJ4mpaTLUr+iZ6A aiKGprBrNCNMU7Mu6Af23peQNo0t+0sdsxp3wjZAMcSK0/ioOnc2R+IZhjHI9dPh Us7Ke/Pa1DRu78T0P2quRvIIRPv5iGep2vL8LFkQtPNS4tAU5ZHTWghVip+Q0m7x 660WwZ5a9Bkzii/mqxFlXnXMnFjaJwi7zEPEKEMKd88cTjZXZGqScq8Ojfxto4Jx mdn9kPqwUR2QILTVKyBy2nJTeCB5nLvLhldi5/1nVxhqopN5ll4VwFx8CVsEPVTQ l76IUMzdAmztnVqs1p7qZ8dyFKdYztNRSESapumpu10/DIIOgWW4eLNk5Sk+7d0K 1fZDL/hWV2j4gnY0wSjGht2JQ2jhDBsgkxInxvQY2a8Ik91gwyUsD7r3mCq/YwaA 97GJHk9YO75jolFPy6PniXttzVuoJXPEcvgpBR3br1iFRQhSoGIEfFcDnZEaH9Sw m7nSc1Q99a6rsmq+WavB5JVPZBr2UkBhE6x+IU+MEBPwykjNj/1cZ7x4rtqzX666 eOn1FBDQ63CLEQl3hAPp1pxy3YB0nHcxKR9CPAZjECwZTfsYgJCrRNHyZb+yhPsU qKKXXMaOyyowoLraGbQ= =Fkue -----END PGP SIGNATURE----- Merge tag 'pmdomain-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm Pull pmdomain updates from Ulf Hansson: "pmdomain core: - Allow power-off for out-of-band wakeup-capable devices - Drop the redundant call to dev_pm_domain_detach() for the amba bus - Extend the genpd governor for CPUs to account for IPIs pmdomain providers: - bcm: Add support for BCM2712 - mediatek: Add support for MFlexGraphics power domains - mediatek: Add support for MT8196 power domains - qcom: Add RPMh power domain support for Kaanapali - rockchip: Add support for RV1126B pmdomain consumers: - usb: dwc3: Enable out of band wakeup for i.MX95 - usb: chipidea: Enable out of band wakeup for i.MX95" * tag 'pmdomain-v6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (26 commits) pmdomain: Extend the genpd governor for CPUs to account for IPIs smp: Introduce a helper function to check for pending IPIs pmdomain: mediatek: convert from clk round_rate() to determine_rate() amba: bus: Drop dev_pm_domain_detach() call pmdomain: bcm: bcm2835-power: Prepare to support BCM2712 pmdomain: mediatek: mtk-mfg: select MAILBOX in Kconfig pmdomain: mediatek: Add support for MFlexGraphics pmdomain: mediatek: Fix build-errors cpuidle: psci: Replace deprecated strcpy in psci_idle_init_cpu pmdomain: rockchip: Add support for RV1126B pmdomain: mediatek: Add support for MT8196 HFRPSYS power domains pmdomain: mediatek: Add support for MT8196 SCPSYS power domains pmdomain: mediatek: Add support for secure HWCCF infra power on pmdomain: mediatek: Add support for Hardware Voter power domains pmdomain: qcom: rpmhpd: Add RPMh power domain support for Kaanapali usb: dwc3: imx8mp: Set out of band wakeup for i.MX95 usb: chipidea: ci_hdrc_imx: Set out of band wakeup for i.MX95 usb: chipidea: core: detach power domain for ci_hdrc platform device pmdomain: core: Allow power-off for out-of-band wakeup-capable devices PM: wakeup: Add out-of-band system wakeup support for devices ...
This commit is contained in:
commit
52206f82d9
|
|
@ -0,0 +1,117 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/power/mediatek,mt8196-gpufreq.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MFlexGraphics Power and Frequency Controller
|
||||
|
||||
maintainers:
|
||||
- Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
|
||||
|
||||
description:
|
||||
A special-purpose embedded MCU to control power and frequency of GPU devices
|
||||
using MediaTek Flexible Graphics integration hardware.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: '^power-controller@[a-f0-9]+$'
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt8196-gpufreq
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: GPR memory area
|
||||
- description: RPC memory area
|
||||
- description: SoC variant ID register
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: gpr
|
||||
- const: rpc
|
||||
- const: hw-revision
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: main clock of the embedded controller (EB)
|
||||
- description: core PLL
|
||||
- description: stack 0 PLL
|
||||
- description: stack 1 PLL
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: eb
|
||||
- const: core
|
||||
- const: stack0
|
||||
- const: stack1
|
||||
|
||||
mboxes:
|
||||
items:
|
||||
- description: FastDVFS events
|
||||
- description: frequency control
|
||||
- description: sleep control
|
||||
- description: timer control
|
||||
- description: frequency hopping control
|
||||
- description: hardware voter control
|
||||
- description: FastDVFS control
|
||||
|
||||
mbox-names:
|
||||
items:
|
||||
- const: fast-dvfs-event
|
||||
- const: gpufreq
|
||||
- const: sleep
|
||||
- const: timer
|
||||
- const: fhctl
|
||||
- const: ccf
|
||||
- const: fast-dvfs
|
||||
|
||||
memory-region:
|
||||
items:
|
||||
- description: phandle to the GPUEB shared memory
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
"#power-domain-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- mboxes
|
||||
- mbox-names
|
||||
- memory-region
|
||||
- "#clock-cells"
|
||||
- "#power-domain-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mediatek,mt8196-clock.h>
|
||||
|
||||
power-controller@4b09fd00 {
|
||||
compatible = "mediatek,mt8196-gpufreq";
|
||||
reg = <0x4b09fd00 0x80>,
|
||||
<0x4b800000 0x1000>,
|
||||
<0x4b860128 0x4>;
|
||||
reg-names = "gpr", "rpc", "hw-revision";
|
||||
clocks = <&topckgen CLK_TOP_MFG_EB>,
|
||||
<&mfgpll CLK_MFG_AO_MFGPLL>,
|
||||
<&mfgpll_sc0 CLK_MFGSC0_AO_MFGPLL_SC0>,
|
||||
<&mfgpll_sc1 CLK_MFGSC1_AO_MFGPLL_SC1>;
|
||||
clock-names = "eb", "core", "stack0", "stack1";
|
||||
mboxes = <&gpueb_mbox 0>, <&gpueb_mbox 1>, <&gpueb_mbox 2>,
|
||||
<&gpueb_mbox 3>, <&gpueb_mbox 4>, <&gpueb_mbox 5>,
|
||||
<&gpueb_mbox 7>;
|
||||
mbox-names = "fast-dvfs-event", "gpufreq", "sleep", "timer", "fhctl",
|
||||
"ccf", "fast-dvfs";
|
||||
memory-region = <&gpueb_shared_memory>;
|
||||
#clock-cells = <1>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
|
|
@ -33,6 +33,9 @@ properties:
|
|||
- mediatek,mt8188-power-controller
|
||||
- mediatek,mt8192-power-controller
|
||||
- mediatek,mt8195-power-controller
|
||||
- mediatek,mt8196-hwv-hfrp-power-controller
|
||||
- mediatek,mt8196-hwv-scp-power-controller
|
||||
- mediatek,mt8196-power-controller
|
||||
- mediatek,mt8365-power-controller
|
||||
|
||||
'#power-domain-cells':
|
||||
|
|
@ -157,6 +160,7 @@ allOf:
|
|||
contains:
|
||||
enum:
|
||||
- mediatek,mt8183-power-controller
|
||||
- mediatek,mt8196-power-controller
|
||||
then:
|
||||
properties:
|
||||
access-controllers:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ properties:
|
|||
oneOf:
|
||||
- enum:
|
||||
- qcom,glymur-rpmhpd
|
||||
- qcom,kaanapali-rpmhpd
|
||||
- qcom,mdm9607-rpmpd
|
||||
- qcom,milos-rpmhpd
|
||||
- qcom,msm8226-rpmpd
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ properties:
|
|||
- rockchip,rk3576-power-controller
|
||||
- rockchip,rk3588-power-controller
|
||||
- rockchip,rv1126-power-controller
|
||||
- rockchip,rv1126b-power-controller
|
||||
|
||||
"#power-domain-cells":
|
||||
const: 1
|
||||
|
|
@ -126,6 +127,7 @@ $defs:
|
|||
"include/dt-bindings/power/rk3568-power.h"
|
||||
"include/dt-bindings/power/rk3588-power.h"
|
||||
"include/dt-bindings/power/rockchip,rv1126-power.h"
|
||||
"include/dt-bindings/power/rockchip,rv1126b-power-controller.h"
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
|
|
|
|||
|
|
@ -13,23 +13,21 @@ description: |
|
|||
maintainers:
|
||||
- Nicolas Saenz Julienne <nsaenz@kernel.org>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/watchdog/watchdog.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- brcm,bcm2835-pm
|
||||
- brcm,bcm2711-pm
|
||||
- brcm,bcm2712-pm
|
||||
- const: brcm,bcm2835-pm-wdt
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
minItems: 1
|
||||
items:
|
||||
- const: pm
|
||||
- const: asb
|
||||
|
|
@ -62,7 +60,35 @@ required:
|
|||
- reg
|
||||
- "#power-domain-cells"
|
||||
- "#reset-cells"
|
||||
- clocks
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/watchdog/watchdog.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- brcm,bcm2835-pm
|
||||
- brcm,bcm2711-pm
|
||||
then:
|
||||
required:
|
||||
- clocks
|
||||
|
||||
properties:
|
||||
reg:
|
||||
minItems: 2
|
||||
|
||||
reg-names:
|
||||
minItems: 2
|
||||
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reg-names:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
|
|
|||
|
|
@ -291,15 +291,14 @@ static int amba_probe(struct device *dev)
|
|||
if (ret < 0)
|
||||
break;
|
||||
|
||||
ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON);
|
||||
ret = dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON |
|
||||
PD_FLAG_DETACH_POWER_OFF);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = amba_get_enable_pclk(pcdev);
|
||||
if (ret) {
|
||||
dev_pm_domain_detach(dev, true);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
|
|
@ -314,7 +313,6 @@ static int amba_probe(struct device *dev)
|
|||
pm_runtime_put_noidle(dev);
|
||||
|
||||
amba_put_disable_pclk(pcdev);
|
||||
dev_pm_domain_detach(dev, true);
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
|
|
@ -336,7 +334,6 @@ static void amba_remove(struct device *dev)
|
|||
pm_runtime_put_noidle(dev);
|
||||
|
||||
amba_put_disable_pclk(pcdev);
|
||||
dev_pm_domain_detach(dev, true);
|
||||
}
|
||||
|
||||
static void amba_shutdown(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -2148,6 +2148,7 @@ static int device_prepare(struct device *dev, pm_message_t state)
|
|||
device_lock(dev);
|
||||
|
||||
dev->power.wakeup_path = false;
|
||||
dev->power.out_band_wakeup = false;
|
||||
|
||||
if (dev->power.no_pm_callbacks)
|
||||
goto unlock;
|
||||
|
|
|
|||
|
|
@ -382,8 +382,8 @@ static int psci_idle_init_cpu(struct device *dev, int cpu)
|
|||
drv->states[0].exit_latency = 1;
|
||||
drv->states[0].target_residency = 1;
|
||||
drv->states[0].power_usage = UINT_MAX;
|
||||
strcpy(drv->states[0].name, "WFI");
|
||||
strcpy(drv->states[0].desc, "ARM WFI");
|
||||
strscpy(drv->states[0].name, "WFI");
|
||||
strscpy(drv->states[0].desc, "ARM WFI");
|
||||
|
||||
/*
|
||||
* If no DT idle states are detected (ret == 0) let the driver
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@
|
|||
#define PM_IMAGE 0x108
|
||||
#define PM_GRAFX 0x10c
|
||||
#define PM_PROC 0x110
|
||||
#define PM_GRAFX_2712 0x304
|
||||
#define PM_ENAB BIT(12)
|
||||
#define PM_ISPRSTN BIT(8)
|
||||
#define PM_H264RSTN BIT(7)
|
||||
|
|
@ -381,6 +382,9 @@ static int bcm2835_power_pd_power_on(struct generic_pm_domain *domain)
|
|||
return bcm2835_power_power_on(pd, PM_GRAFX);
|
||||
|
||||
case BCM2835_POWER_DOMAIN_GRAFX_V3D:
|
||||
if (!power->asb)
|
||||
return bcm2835_asb_power_on(pd, PM_GRAFX_2712,
|
||||
0, 0, PM_V3DRSTN);
|
||||
return bcm2835_asb_power_on(pd, PM_GRAFX,
|
||||
ASB_V3D_M_CTRL, ASB_V3D_S_CTRL,
|
||||
PM_V3DRSTN);
|
||||
|
|
@ -447,6 +451,9 @@ static int bcm2835_power_pd_power_off(struct generic_pm_domain *domain)
|
|||
return bcm2835_power_power_off(pd, PM_GRAFX);
|
||||
|
||||
case BCM2835_POWER_DOMAIN_GRAFX_V3D:
|
||||
if (!power->asb)
|
||||
return bcm2835_asb_power_off(pd, PM_GRAFX_2712,
|
||||
0, 0, PM_V3DRSTN);
|
||||
return bcm2835_asb_power_off(pd, PM_GRAFX,
|
||||
ASB_V3D_M_CTRL, ASB_V3D_S_CTRL,
|
||||
PM_V3DRSTN);
|
||||
|
|
@ -635,10 +642,12 @@ static int bcm2835_power_probe(struct platform_device *pdev)
|
|||
power->asb = pm->asb;
|
||||
power->rpivid_asb = pm->rpivid_asb;
|
||||
|
||||
id = readl(power->asb + ASB_AXI_BRDG_ID);
|
||||
if (id != BCM2835_BRDG_ID /* "BRDG" */) {
|
||||
dev_err(dev, "ASB register ID returned 0x%08x\n", id);
|
||||
return -ENODEV;
|
||||
if (power->asb) {
|
||||
id = readl(power->asb + ASB_AXI_BRDG_ID);
|
||||
if (id != BCM2835_BRDG_ID /* "BRDG" */) {
|
||||
dev_err(dev, "ASB register ID returned 0x%08x\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (power->rpivid_asb) {
|
||||
|
|
|
|||
|
|
@ -1551,7 +1551,8 @@ static int genpd_finish_suspend(struct device *dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (device_awake_path(dev) && genpd_is_active_wakeup(genpd))
|
||||
if (device_awake_path(dev) && genpd_is_active_wakeup(genpd) &&
|
||||
!device_out_band_wakeup(dev))
|
||||
return 0;
|
||||
|
||||
if (genpd->dev_ops.stop && genpd->dev_ops.start &&
|
||||
|
|
@ -1606,7 +1607,8 @@ static int genpd_finish_resume(struct device *dev,
|
|||
if (IS_ERR(genpd))
|
||||
return -EINVAL;
|
||||
|
||||
if (device_awake_path(dev) && genpd_is_active_wakeup(genpd))
|
||||
if (device_awake_path(dev) && genpd_is_active_wakeup(genpd) &&
|
||||
!device_out_band_wakeup(dev))
|
||||
return resume_noirq(dev);
|
||||
|
||||
genpd_lock(genpd);
|
||||
|
|
|
|||
|
|
@ -408,15 +408,21 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd)
|
|||
if ((idle_duration_ns >= (genpd->states[i].residency_ns +
|
||||
genpd->states[i].power_off_latency_ns)) &&
|
||||
(global_constraint >= (genpd->states[i].power_on_latency_ns +
|
||||
genpd->states[i].power_off_latency_ns))) {
|
||||
genpd->state_idx = i;
|
||||
genpd->gd->last_enter = now;
|
||||
genpd->gd->reflect_residency = true;
|
||||
return true;
|
||||
}
|
||||
genpd->states[i].power_off_latency_ns)))
|
||||
break;
|
||||
|
||||
} while (--i >= 0);
|
||||
|
||||
return false;
|
||||
if (i < 0)
|
||||
return false;
|
||||
|
||||
if (cpus_peek_for_pending_ipi(genpd->cpus))
|
||||
return false;
|
||||
|
||||
genpd->state_idx = i;
|
||||
genpd->gd->last_enter = now;
|
||||
genpd->gd->reflect_residency = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cpu_system_power_down_ok(struct dev_pm_domain *pd)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,23 @@ config MTK_SCPSYS_PM_DOMAINS
|
|||
Control Processor System (SCPSYS) has several power management related
|
||||
tasks in the system.
|
||||
|
||||
config MTK_MFG_PM_DOMAIN
|
||||
bool "MediaTek MFlexGraphics power domain"
|
||||
default ARCH_MEDIATEK
|
||||
depends on PM
|
||||
depends on OF
|
||||
depends on COMMON_CLK
|
||||
select MAILBOX
|
||||
select PM_GENERIC_DOMAINS
|
||||
imply MTK_GPUEB_MBOX
|
||||
help
|
||||
Say y or m here to enable the power domains driver for MediaTek
|
||||
MFlexGraphics. This driver allows for power and frequency control of
|
||||
GPUs on MediaTek SoCs such as the MT8196 or MT6991.
|
||||
|
||||
This driver is required for the Mali GPU to work at all on MT8196 and
|
||||
MT6991.
|
||||
|
||||
config AIROHA_CPU_PM_DOMAIN
|
||||
tristate "Airoha CPU power domain"
|
||||
default ARCH_AIROHA
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_MTK_MFG_PM_DOMAIN) += mtk-mfg-pmdomain.o
|
||||
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
|
||||
obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
|
||||
obj-$(CONFIG_AIROHA_CPU_PM_DOMAIN) += airoha-cpu-pmdomain.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,625 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2025 Collabora Ltd
|
||||
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
*/
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8196_PM_DOMAINS_H
|
||||
#define __SOC_MEDIATEK_MT8196_PM_DOMAINS_H
|
||||
|
||||
#include "mtk-pm-domains.h"
|
||||
#include <dt-bindings/power/mediatek,mt8196-power.h>
|
||||
|
||||
/*
|
||||
* MT8196 and MT6991 power domain support
|
||||
*/
|
||||
|
||||
/* INFRA TOP_AXI registers */
|
||||
#define MT8196_TOP_AXI_PROT_EN_SET 0x4
|
||||
#define MT8196_TOP_AXI_PROT_EN_CLR 0x8
|
||||
#define MT8196_TOP_AXI_PROT_EN_STA 0xc
|
||||
#define MT8196_TOP_AXI_PROT_EN_SLEEP0_MD BIT(29)
|
||||
|
||||
#define MT8196_TOP_AXI_PROT_EN_1_SET 0x24
|
||||
#define MT8196_TOP_AXI_PROT_EN_1_CLR 0x28
|
||||
#define MT8196_TOP_AXI_PROT_EN_1_STA 0x2c
|
||||
#define MT8196_TOP_AXI_PROT_EN_1_SLEEP1_MD BIT(0)
|
||||
|
||||
/* SPM BUS_PROTECT registers */
|
||||
#define MT8196_SPM_BUS_PROTECT_CON_SET 0xdc
|
||||
#define MT8196_SPM_BUS_PROTECT_CON_CLR 0xe0
|
||||
#define MT8196_SPM_BUS_PROTECT_RDY 0x208
|
||||
#define MT8196_SPM_PROT_EN_BUS_CONN BIT(1)
|
||||
#define MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0 BIT(6)
|
||||
#define MT8196_SPM_PROT_EN_BUS_SSUSB_P0 BIT(7)
|
||||
#define MT8196_SPM_PROT_EN_BUS_SSUSB_P1 BIT(8)
|
||||
#define MT8196_SPM_PROT_EN_BUS_SSUSB_P23 BIT(9)
|
||||
#define MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2 BIT(10)
|
||||
#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0 BIT(13)
|
||||
#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1 BIT(14)
|
||||
#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2 BIT(15)
|
||||
#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0 BIT(16)
|
||||
#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1 BIT(17)
|
||||
#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2 BIT(18)
|
||||
#define MT8196_SPM_PROT_EN_BUS_AUDIO BIT(19)
|
||||
#define MT8196_SPM_PROT_EN_BUS_ADSP_TOP BIT(21)
|
||||
#define MT8196_SPM_PROT_EN_BUS_ADSP_INFRA BIT(22)
|
||||
#define MT8196_SPM_PROT_EN_BUS_ADSP_AO BIT(23)
|
||||
#define MT8196_SPM_PROT_EN_BUS_MM_PROC BIT(24)
|
||||
|
||||
/* PWR_CON registers */
|
||||
#define MT8196_PWR_ACK BIT(30)
|
||||
#define MT8196_PWR_ACK_2ND BIT(31)
|
||||
|
||||
static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8196[] = {
|
||||
BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_SPM
|
||||
};
|
||||
|
||||
static const struct scpsys_domain_data scpsys_domain_data_mt8196[] = {
|
||||
[MT8196_POWER_DOMAIN_MD] = {
|
||||
.name = "md",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe00,
|
||||
.pwr_sta_offs = 0xe00,
|
||||
.pwr_sta2nd_offs = 0xe00,
|
||||
.ext_buck_iso_offs = 0xefc,
|
||||
.ext_buck_iso_mask = GENMASK(1, 0),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA, MT8196_TOP_AXI_PROT_EN_SLEEP0_MD,
|
||||
MT8196_TOP_AXI_PROT_EN_SET,
|
||||
MT8196_TOP_AXI_PROT_EN_CLR,
|
||||
MT8196_TOP_AXI_PROT_EN_STA),
|
||||
BUS_PROT_WR_IGN(INFRA, MT8196_TOP_AXI_PROT_EN_1_SLEEP1_MD,
|
||||
MT8196_TOP_AXI_PROT_EN_1_SET,
|
||||
MT8196_TOP_AXI_PROT_EN_1_CLR,
|
||||
MT8196_TOP_AXI_PROT_EN_1_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_MODEM_PWRSEQ | MTK_SCPD_EXT_BUCK_ISO |
|
||||
MTK_SCPD_SKIP_RESET_B | MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_CONN] = {
|
||||
.name = "conn",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe04,
|
||||
.pwr_sta_offs = 0xe04,
|
||||
.pwr_sta2nd_offs = 0xe04,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_CONN,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0] = {
|
||||
.name = "ssusb-dp-phy-p0",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe18,
|
||||
.pwr_sta_offs = 0xe18,
|
||||
.pwr_sta2nd_offs = 0xe18,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_ALWAYS_ON,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_SSUSB_P0] = {
|
||||
.name = "ssusb-p0",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe1c,
|
||||
.pwr_sta_offs = 0xe1c,
|
||||
.pwr_sta2nd_offs = 0xe1c,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_P0,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_ALWAYS_ON,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_SSUSB_P1] = {
|
||||
.name = "ssusb-p1",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe20,
|
||||
.pwr_sta_offs = 0xe20,
|
||||
.pwr_sta2nd_offs = 0xe20,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_P1,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_ALWAYS_ON,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_SSUSB_P23] = {
|
||||
.name = "ssusb-p23",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe24,
|
||||
.pwr_sta_offs = 0xe24,
|
||||
.pwr_sta2nd_offs = 0xe24,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_P23,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_SSUSB_PHY_P2] = {
|
||||
.name = "ssusb-phy-p2",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe28,
|
||||
.pwr_sta_offs = 0xe28,
|
||||
.pwr_sta2nd_offs = 0xe28,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_PEXTP_MAC0] = {
|
||||
.name = "pextp-mac0",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe34,
|
||||
.pwr_sta_offs = 0xe34,
|
||||
.pwr_sta2nd_offs = 0xe34,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_PCIE_PHY,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_PEXTP_MAC1] = {
|
||||
.name = "pextp-mac1",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe38,
|
||||
.pwr_sta_offs = 0xe38,
|
||||
.pwr_sta2nd_offs = 0xe38,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_PCIE_PHY,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_PEXTP_MAC2] = {
|
||||
.name = "pextp-mac2",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe3c,
|
||||
.pwr_sta_offs = 0xe3c,
|
||||
.pwr_sta2nd_offs = 0xe3c,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_PCIE_PHY,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_PEXTP_PHY0] = {
|
||||
.name = "pextp-phy0",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe40,
|
||||
.pwr_sta_offs = 0xe40,
|
||||
.pwr_sta2nd_offs = 0xe40,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_PCIE_PHY,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_PEXTP_PHY1] = {
|
||||
.name = "pextp-phy1",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe44,
|
||||
.pwr_sta_offs = 0xe44,
|
||||
.pwr_sta2nd_offs = 0xe44,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_PCIE_PHY,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_PEXTP_PHY2] = {
|
||||
.name = "pextp-phy2",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe48,
|
||||
.pwr_sta_offs = 0xe48,
|
||||
.pwr_sta2nd_offs = 0xe48,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_PCIE_PHY,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_AUDIO] = {
|
||||
.name = "audio",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe4c,
|
||||
.pwr_sta_offs = 0xe4c,
|
||||
.pwr_sta2nd_offs = 0xe4c,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_AUDIO,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT] = {
|
||||
.name = "adsp-top-dormant",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe54,
|
||||
.pwr_sta_offs = 0xe54,
|
||||
.pwr_sta2nd_offs = 0xe54,
|
||||
/* Note: This is not managing powerdown (pdn), but sleep instead (slp) */
|
||||
.sram_pdn_bits = BIT(9),
|
||||
.sram_pdn_ack_bits = BIT(13),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_ADSP_TOP,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_SRAM_PDN_INVERTED,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_ADSP_INFRA] = {
|
||||
.name = "adsp-infra",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe58,
|
||||
.pwr_sta_offs = 0xe58,
|
||||
.pwr_sta2nd_offs = 0xe58,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_ADSP_INFRA,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_ALWAYS_ON,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_ADSP_AO] = {
|
||||
.name = "adsp-ao",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe5c,
|
||||
.pwr_sta_offs = 0xe5c,
|
||||
.pwr_sta2nd_offs = 0xe5c,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_ADSP_AO,
|
||||
MT8196_SPM_BUS_PROTECT_CON_SET,
|
||||
MT8196_SPM_BUS_PROTECT_CON_CLR,
|
||||
MT8196_SPM_BUS_PROTECT_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_ALWAYS_ON,
|
||||
.rtff_type = SCPSYS_RTFF_TYPE_GENERIC,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_hwv_domain_data scpsys_hwv_domain_data_mt8196[] = {
|
||||
[MT8196_POWER_DOMAIN_MM_PROC_DORMANT] = {
|
||||
.name = "mm-proc-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021c,
|
||||
.done = 0x141c,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146c,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 0,
|
||||
.caps = MTK_SCPD_ALWAYS_ON,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_SSR] = {
|
||||
.name = "ssrsys",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021c,
|
||||
.done = 0x141c,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146c,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_hwv_domain_data hfrpsys_hwv_domain_data_mt8196[] = {
|
||||
[MT8196_POWER_DOMAIN_VDE0] = {
|
||||
.name = "vde0",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 7,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_VDE1] = {
|
||||
.name = "vde1",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 8,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_VDE_VCORE0] = {
|
||||
.name = "vde-vcore0",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 9,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_VEN0] = {
|
||||
.name = "ven0",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 10,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_VEN1] = {
|
||||
.name = "ven1",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 11,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_VEN2] = {
|
||||
.name = "ven2",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 12,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DISP_VCORE] = {
|
||||
.name = "disp-vcore",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 24,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DIS0_DORMANT] = {
|
||||
.name = "dis0-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 25,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DIS1_DORMANT] = {
|
||||
.name = "dis1-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 26,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_OVL0_DORMANT] = {
|
||||
.name = "ovl0-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 27,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_OVL1_DORMANT] = {
|
||||
.name = "ovl1-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 28,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT] = {
|
||||
.name = "disp-edptx-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 29,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT] = {
|
||||
.name = "disp-dptx-dormant",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 30,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_MML0_SHUTDOWN] = {
|
||||
.name = "mml0-shutdown",
|
||||
.set = 0x0218,
|
||||
.clr = 0x021C,
|
||||
.done = 0x141C,
|
||||
.en = 0x1410,
|
||||
.set_sta = 0x146C,
|
||||
.clr_sta = 0x1470,
|
||||
.setclr_bit = 31,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_MML1_SHUTDOWN] = {
|
||||
.name = "mml1-shutdown",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 0,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_MM_INFRA0] = {
|
||||
.name = "mm-infra0",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 1,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_MM_INFRA1] = {
|
||||
.name = "mm-infra1",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 2,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_MM_INFRA_AO] = {
|
||||
.name = "mm-infra-ao",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 3,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_CSI_BS_RX] = {
|
||||
.name = "csi-bs-rx",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 5,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_CSI_LS_RX] = {
|
||||
.name = "csi-ls-rx",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 6,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DSI_PHY0] = {
|
||||
.name = "dsi-phy0",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 7,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DSI_PHY1] = {
|
||||
.name = "dsi-phy1",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 8,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DSI_PHY2] = {
|
||||
.name = "dsi-phy2",
|
||||
.set = 0x0220,
|
||||
.clr = 0x0224,
|
||||
.done = 0x142C,
|
||||
.en = 0x1420,
|
||||
.set_sta = 0x1474,
|
||||
.clr_sta = 0x1478,
|
||||
.setclr_bit = 9,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8196_scpsys_data = {
|
||||
.domains_data = scpsys_domain_data_mt8196,
|
||||
.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8196),
|
||||
.bus_prot_blocks = scpsys_bus_prot_blocks_mt8196,
|
||||
.num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8196),
|
||||
.type = SCPSYS_MTCMOS_TYPE_DIRECT_CTL,
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8196_scpsys_hwv_data = {
|
||||
.hwv_domains_data = scpsys_hwv_domain_data_mt8196,
|
||||
.num_hwv_domains = ARRAY_SIZE(scpsys_hwv_domain_data_mt8196),
|
||||
.type = SCPSYS_MTCMOS_TYPE_HW_VOTER,
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8196_hfrpsys_hwv_data = {
|
||||
.hwv_domains_data = hfrpsys_hwv_domain_data_mt8196,
|
||||
.num_hwv_domains = ARRAY_SIZE(hfrpsys_hwv_domain_data_mt8196),
|
||||
.type = SCPSYS_MTCMOS_TYPE_HW_VOTER,
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8196_PM_DOMAINS_H */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -2,6 +2,7 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Collabora Ltd.
|
||||
*/
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -15,6 +16,7 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/soc/mediatek/infracfg.h>
|
||||
#include <linux/soc/mediatek/mtk_sip_svc.h>
|
||||
|
||||
#include "mt6735-pm-domains.h"
|
||||
#include "mt6795-pm-domains.h"
|
||||
|
|
@ -26,11 +28,18 @@
|
|||
#include "mt8188-pm-domains.h"
|
||||
#include "mt8192-pm-domains.h"
|
||||
#include "mt8195-pm-domains.h"
|
||||
#include "mt8196-pm-domains.h"
|
||||
#include "mt8365-pm-domains.h"
|
||||
|
||||
#define MTK_POLL_DELAY_US 10
|
||||
#define MTK_POLL_TIMEOUT USEC_PER_SEC
|
||||
|
||||
#define MTK_HWV_POLL_DELAY_US 5
|
||||
#define MTK_HWV_POLL_TIMEOUT (300 * USEC_PER_MSEC)
|
||||
|
||||
#define MTK_HWV_PREPARE_DELAY_US 1
|
||||
#define MTK_HWV_PREPARE_TIMEOUT (3 * USEC_PER_MSEC)
|
||||
|
||||
#define PWR_RST_B_BIT BIT(0)
|
||||
#define PWR_ISO_BIT BIT(1)
|
||||
#define PWR_ON_BIT BIT(2)
|
||||
|
|
@ -45,9 +54,12 @@
|
|||
#define PWR_RTFF_SAVE_FLAG BIT(27)
|
||||
#define PWR_RTFF_UFS_CLK_DIS BIT(28)
|
||||
|
||||
#define MTK_SIP_KERNEL_HWCCF_CONTROL MTK_SIP_SMC_CMD(0x540)
|
||||
|
||||
struct scpsys_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
const struct scpsys_domain_data *data;
|
||||
const struct scpsys_hwv_domain_data *hwv_data;
|
||||
struct scpsys *scpsys;
|
||||
int num_clks;
|
||||
struct clk_bulk_data *clks;
|
||||
|
|
@ -71,18 +83,56 @@ struct scpsys {
|
|||
static bool scpsys_domain_is_on(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
u32 status, status2;
|
||||
u32 mask = pd->data->sta_mask;
|
||||
u32 status, status2, mask2;
|
||||
|
||||
mask2 = pd->data->sta2nd_mask ? pd->data->sta2nd_mask : mask;
|
||||
|
||||
regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status);
|
||||
status &= pd->data->sta_mask;
|
||||
status &= mask;
|
||||
|
||||
regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2);
|
||||
status2 &= pd->data->sta_mask;
|
||||
status2 &= mask2;
|
||||
|
||||
/* A domain is on when both status bits are set. */
|
||||
return status && status2;
|
||||
}
|
||||
|
||||
static bool scpsys_hwv_domain_is_disable_done(struct scpsys_domain *pd)
|
||||
{
|
||||
const struct scpsys_hwv_domain_data *hwv = pd->hwv_data;
|
||||
u32 regs[2] = { hwv->done, hwv->clr_sta };
|
||||
u32 val[2];
|
||||
u32 mask = BIT(hwv->setclr_bit);
|
||||
|
||||
regmap_multi_reg_read(pd->scpsys->base, regs, val, 2);
|
||||
|
||||
/* Disable is done when the bit is set in DONE, cleared in CLR_STA */
|
||||
return (val[0] & mask) && !(val[1] & mask);
|
||||
}
|
||||
|
||||
static bool scpsys_hwv_domain_is_enable_done(struct scpsys_domain *pd)
|
||||
{
|
||||
const struct scpsys_hwv_domain_data *hwv = pd->hwv_data;
|
||||
u32 regs[3] = { hwv->done, hwv->en, hwv->set_sta };
|
||||
u32 val[3];
|
||||
u32 mask = BIT(hwv->setclr_bit);
|
||||
|
||||
regmap_multi_reg_read(pd->scpsys->base, regs, val, 3);
|
||||
|
||||
/* Enable is done when the bit is set in DONE and EN, cleared in SET_STA */
|
||||
return (val[0] & mask) && (val[1] & mask) && !(val[2] & mask);
|
||||
}
|
||||
|
||||
static int scpsys_sec_infra_power_on(bool on)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
unsigned long cmd = on ? 1 : 0;
|
||||
|
||||
arm_smccc_smc(MTK_SIP_KERNEL_HWCCF_CONTROL, cmd, 0, 0, 0, 0, 0, 0, &res);
|
||||
return res.a0;
|
||||
}
|
||||
|
||||
static int scpsys_sram_enable(struct scpsys_domain *pd)
|
||||
{
|
||||
u32 expected_ack, pdn_ack = pd->data->sram_pdn_ack_bits;
|
||||
|
|
@ -250,6 +300,161 @@ static int scpsys_regulator_disable(struct regulator *supply)
|
|||
return supply ? regulator_disable(supply) : 0;
|
||||
}
|
||||
|
||||
static int scpsys_hwv_power_on(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
const struct scpsys_hwv_domain_data *hwv = pd->hwv_data;
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) {
|
||||
ret = scpsys_sec_infra_power_on(true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = scpsys_regulator_enable(pd->supply);
|
||||
if (ret)
|
||||
goto err_infra;
|
||||
|
||||
ret = clk_bulk_prepare_enable(pd->num_clks, pd->clks);
|
||||
if (ret)
|
||||
goto err_reg;
|
||||
|
||||
/* For HWV the subsys clocks refer to the HWV low power subsystem */
|
||||
ret = clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks);
|
||||
if (ret)
|
||||
goto err_disable_clks;
|
||||
|
||||
/* Make sure the HW Voter is idle and able to accept commands */
|
||||
ret = regmap_read_poll_timeout_atomic(scpsys->base, hwv->done, val,
|
||||
val & BIT(hwv->setclr_bit),
|
||||
MTK_HWV_POLL_DELAY_US,
|
||||
MTK_HWV_POLL_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(scpsys->dev, "Failed to power on: HW Voter busy.\n");
|
||||
goto err_disable_subsys_clks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Instruct the HWV to power on the MTCMOS (power domain): after that,
|
||||
* the same bit will be unset immediately by the hardware.
|
||||
*/
|
||||
regmap_write(scpsys->base, hwv->set, BIT(hwv->setclr_bit));
|
||||
|
||||
/*
|
||||
* Wait until the HWV sets the bit again, signalling that its internal
|
||||
* state machine was started and it now processing the vote command.
|
||||
*/
|
||||
ret = regmap_read_poll_timeout_atomic(scpsys->base, hwv->set, val,
|
||||
val & BIT(hwv->setclr_bit),
|
||||
MTK_HWV_PREPARE_DELAY_US,
|
||||
MTK_HWV_PREPARE_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(scpsys->dev, "Failed to power on: HW Voter not starting.\n");
|
||||
goto err_disable_subsys_clks;
|
||||
}
|
||||
|
||||
/* Wait for ACK, signalling that the MTCMOS was enabled */
|
||||
ret = readx_poll_timeout_atomic(scpsys_hwv_domain_is_enable_done, pd, val, val,
|
||||
MTK_HWV_POLL_DELAY_US, MTK_HWV_POLL_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(scpsys->dev, "Failed to power on: HW Voter ACK timeout.\n");
|
||||
goto err_disable_subsys_clks;
|
||||
}
|
||||
|
||||
/* It's done! Disable the HWV low power subsystem clocks */
|
||||
clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL))
|
||||
scpsys_sec_infra_power_on(false);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_subsys_clks:
|
||||
clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
err_disable_clks:
|
||||
clk_bulk_disable_unprepare(pd->num_clks, pd->clks);
|
||||
err_reg:
|
||||
scpsys_regulator_disable(pd->supply);
|
||||
err_infra:
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL))
|
||||
scpsys_sec_infra_power_on(false);
|
||||
return ret;
|
||||
};
|
||||
|
||||
static int scpsys_hwv_power_off(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
const struct scpsys_hwv_domain_data *hwv = pd->hwv_data;
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) {
|
||||
ret = scpsys_sec_infra_power_on(true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks);
|
||||
if (ret)
|
||||
goto err_infra;
|
||||
|
||||
/* Make sure the HW Voter is idle and able to accept commands */
|
||||
ret = regmap_read_poll_timeout_atomic(scpsys->base, hwv->done, val,
|
||||
val & BIT(hwv->setclr_bit),
|
||||
MTK_HWV_POLL_DELAY_US,
|
||||
MTK_HWV_POLL_TIMEOUT);
|
||||
if (ret)
|
||||
goto err_disable_subsys_clks;
|
||||
|
||||
|
||||
/*
|
||||
* Instruct the HWV to power off the MTCMOS (power domain): differently
|
||||
* from poweron, the bit will be kept set.
|
||||
*/
|
||||
regmap_write(scpsys->base, hwv->clr, BIT(hwv->setclr_bit));
|
||||
|
||||
/*
|
||||
* Wait until the HWV clears the bit, signalling that its internal
|
||||
* state machine was started and it now processing the clear command.
|
||||
*/
|
||||
ret = regmap_read_poll_timeout_atomic(scpsys->base, hwv->clr, val,
|
||||
!(val & BIT(hwv->setclr_bit)),
|
||||
MTK_HWV_PREPARE_DELAY_US,
|
||||
MTK_HWV_PREPARE_TIMEOUT);
|
||||
if (ret)
|
||||
goto err_disable_subsys_clks;
|
||||
|
||||
/* Poweroff needs 100us for the HW to stabilize */
|
||||
udelay(100);
|
||||
|
||||
/* Wait for ACK, signalling that the MTCMOS was disabled */
|
||||
ret = readx_poll_timeout_atomic(scpsys_hwv_domain_is_disable_done, pd, val, val,
|
||||
MTK_HWV_POLL_DELAY_US, MTK_HWV_POLL_TIMEOUT);
|
||||
if (ret)
|
||||
goto err_disable_subsys_clks;
|
||||
|
||||
clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
clk_bulk_disable_unprepare(pd->num_clks, pd->clks);
|
||||
|
||||
scpsys_regulator_disable(pd->supply);
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL))
|
||||
scpsys_sec_infra_power_on(false);
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_subsys_clks:
|
||||
clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
err_infra:
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL))
|
||||
scpsys_sec_infra_power_on(false);
|
||||
return ret;
|
||||
};
|
||||
|
||||
static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
|
|
@ -514,6 +719,7 @@ static struct
|
|||
generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node)
|
||||
{
|
||||
const struct scpsys_domain_data *domain_data;
|
||||
const struct scpsys_hwv_domain_data *hwv_domain_data;
|
||||
struct scpsys_domain *pd;
|
||||
struct property *prop;
|
||||
const char *clk_name;
|
||||
|
|
@ -529,14 +735,33 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (id >= scpsys->soc_data->num_domains) {
|
||||
dev_err(scpsys->dev, "%pOF: invalid domain id %d\n", node, id);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
switch (scpsys->soc_data->type) {
|
||||
case SCPSYS_MTCMOS_TYPE_DIRECT_CTL:
|
||||
if (id >= scpsys->soc_data->num_domains) {
|
||||
dev_err(scpsys->dev, "%pOF: invalid domain id %d\n", node, id);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
domain_data = &scpsys->soc_data->domains_data[id];
|
||||
if (domain_data->sta_mask == 0) {
|
||||
dev_err(scpsys->dev, "%pOF: undefined domain id %d\n", node, id);
|
||||
domain_data = &scpsys->soc_data->domains_data[id];
|
||||
hwv_domain_data = NULL;
|
||||
|
||||
if (domain_data->sta_mask == 0) {
|
||||
dev_err(scpsys->dev, "%pOF: undefined domain id %d\n", node, id);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
break;
|
||||
case SCPSYS_MTCMOS_TYPE_HW_VOTER:
|
||||
if (id >= scpsys->soc_data->num_hwv_domains) {
|
||||
dev_err(scpsys->dev, "%pOF: invalid HWV domain id %d\n", node, id);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
domain_data = NULL;
|
||||
hwv_domain_data = &scpsys->soc_data->hwv_domains_data[id];
|
||||
|
||||
break;
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
|
@ -545,6 +770,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pd->data = domain_data;
|
||||
pd->hwv_data = hwv_domain_data;
|
||||
pd->scpsys = scpsys;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_DOMAIN_SUPPLY)) {
|
||||
|
|
@ -604,6 +830,31 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
pd->subsys_clks[i].clk = clk;
|
||||
}
|
||||
|
||||
if (scpsys->domains[id]) {
|
||||
ret = -EINVAL;
|
||||
dev_err(scpsys->dev,
|
||||
"power domain with id %d already exists, check your device-tree\n", id);
|
||||
goto err_put_subsys_clocks;
|
||||
}
|
||||
|
||||
if (pd->data && pd->data->name)
|
||||
pd->genpd.name = pd->data->name;
|
||||
else if (pd->hwv_data && pd->hwv_data->name)
|
||||
pd->genpd.name = pd->hwv_data->name;
|
||||
else
|
||||
pd->genpd.name = node->name;
|
||||
|
||||
if (scpsys->soc_data->type == SCPSYS_MTCMOS_TYPE_DIRECT_CTL) {
|
||||
pd->genpd.power_off = scpsys_power_off;
|
||||
pd->genpd.power_on = scpsys_power_on;
|
||||
} else {
|
||||
pd->genpd.power_off = scpsys_hwv_power_off;
|
||||
pd->genpd.power_on = scpsys_hwv_power_on;
|
||||
|
||||
/* HW-Voter code can be invoked in atomic context */
|
||||
pd->genpd.flags |= GENPD_FLAG_IRQ_SAFE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initially turn on all domains to make the domains usable
|
||||
* with !CONFIG_PM and to get the hardware in sync with the
|
||||
|
|
@ -615,7 +866,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
dev_warn(scpsys->dev,
|
||||
"%pOF: A default off power domain has been ON\n", node);
|
||||
} else {
|
||||
ret = scpsys_power_on(&pd->genpd);
|
||||
ret = pd->genpd.power_on(&pd->genpd);
|
||||
if (ret < 0) {
|
||||
dev_err(scpsys->dev, "%pOF: failed to power on domain: %d\n", node, ret);
|
||||
goto err_put_subsys_clocks;
|
||||
|
|
@ -625,21 +876,6 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
|
||||
}
|
||||
|
||||
if (scpsys->domains[id]) {
|
||||
ret = -EINVAL;
|
||||
dev_err(scpsys->dev,
|
||||
"power domain with id %d already exists, check your device-tree\n", id);
|
||||
goto err_put_subsys_clocks;
|
||||
}
|
||||
|
||||
if (!pd->data->name)
|
||||
pd->genpd.name = node->name;
|
||||
else
|
||||
pd->genpd.name = pd->data->name;
|
||||
|
||||
pd->genpd.power_off = scpsys_power_off;
|
||||
pd->genpd.power_on = scpsys_power_on;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_ACTIVE_WAKEUP))
|
||||
pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
|
||||
|
||||
|
|
@ -931,6 +1167,18 @@ static const struct of_device_id scpsys_of_match[] = {
|
|||
.compatible = "mediatek,mt8195-power-controller",
|
||||
.data = &mt8195_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8196-power-controller",
|
||||
.data = &mt8196_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8196-hwv-hfrp-power-controller",
|
||||
.data = &mt8196_hfrpsys_hwv_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8196-hwv-scp-power-controller",
|
||||
.data = &mt8196_scpsys_hwv_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8365-power-controller",
|
||||
.data = &mt8365_scpsys_data,
|
||||
|
|
@ -946,7 +1194,7 @@ static int scpsys_probe(struct platform_device *pdev)
|
|||
struct device_node *node;
|
||||
struct device *parent;
|
||||
struct scpsys *scpsys;
|
||||
int ret;
|
||||
int num_domains, ret;
|
||||
|
||||
soc = of_device_get_match_data(&pdev->dev);
|
||||
if (!soc) {
|
||||
|
|
@ -954,7 +1202,9 @@ static int scpsys_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
scpsys = devm_kzalloc(dev, struct_size(scpsys, domains, soc->num_domains), GFP_KERNEL);
|
||||
num_domains = soc->num_domains + soc->num_hwv_domains;
|
||||
|
||||
scpsys = devm_kzalloc(dev, struct_size(scpsys, domains, num_domains), GFP_KERNEL);
|
||||
if (!scpsys)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@
|
|||
#define MTK_SCPD_SRAM_PDN_INVERTED BIT(9)
|
||||
#define MTK_SCPD_MODEM_PWRSEQ BIT(10)
|
||||
#define MTK_SCPD_SKIP_RESET_B BIT(11)
|
||||
#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
|
||||
#define MTK_SCPD_INFRA_PWR_CTL BIT(12)
|
||||
#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data ? \
|
||||
(_scpd)->data->caps & (_x) : \
|
||||
(_scpd)->hwv_data->caps & (_x))
|
||||
|
||||
#define SPM_VDE_PWR_CON 0x0210
|
||||
#define SPM_MFG_PWR_CON 0x0214
|
||||
|
|
@ -59,6 +62,7 @@ enum scpsys_bus_prot_block {
|
|||
BUS_PROT_BLOCK_INFRA,
|
||||
BUS_PROT_BLOCK_INFRA_NAO,
|
||||
BUS_PROT_BLOCK_SMI,
|
||||
BUS_PROT_BLOCK_SPM,
|
||||
BUS_PROT_BLOCK_COUNT,
|
||||
};
|
||||
|
||||
|
|
@ -124,10 +128,23 @@ enum scpsys_rtff_type {
|
|||
SCPSYS_RTFF_TYPE_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* enum scpsys_mtcmos_type - Type of power domain controller
|
||||
* @SCPSYS_MTCMOS_TYPE_DIRECT_CTL: Power domains are controlled with direct access
|
||||
* @SCPSYS_MTCMOS_TYPE_HW_VOTER: Hardware-assisted voted power domain control
|
||||
* @SCPSYS_MTCMOS_TYPE_MAX: Number of supported power domain types
|
||||
*/
|
||||
enum scpsys_mtcmos_type {
|
||||
SCPSYS_MTCMOS_TYPE_DIRECT_CTL = 0,
|
||||
SCPSYS_MTCMOS_TYPE_HW_VOTER,
|
||||
SCPSYS_MTCMOS_TYPE_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* struct scpsys_domain_data - scp domain data for power on/off flow
|
||||
* @name: The name of the power domain.
|
||||
* @sta_mask: The mask for power on/off status bit.
|
||||
* @sta2nd_mask: The mask for second power on/off status bit.
|
||||
* @ctl_offs: The offset for main power control register.
|
||||
* @sram_pdn_bits: The mask for sram power control bits.
|
||||
* @sram_pdn_ack_bits: The mask for sram power control acked bits.
|
||||
|
|
@ -140,6 +157,7 @@ enum scpsys_rtff_type {
|
|||
struct scpsys_domain_data {
|
||||
const char *name;
|
||||
u32 sta_mask;
|
||||
u32 sta2nd_mask;
|
||||
int ctl_offs;
|
||||
u32 sram_pdn_bits;
|
||||
u32 sram_pdn_ack_bits;
|
||||
|
|
@ -152,11 +170,40 @@ struct scpsys_domain_data {
|
|||
int pwr_sta2nd_offs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct scpsys_hwv_domain_data - Hardware Voter power domain data
|
||||
* @name: Name of the power domain
|
||||
* @set: Offset of the HWV SET register
|
||||
* @clr: Offset of the HWV CLEAR register
|
||||
* @done: Offset of the HWV DONE register
|
||||
* @en: Offset of the HWV ENABLE register
|
||||
* @set_sta: Offset of the HWV SET STATUS register
|
||||
* @clr_sta: Offset of the HWV CLEAR STATUS register
|
||||
* @setclr_bit: The SET/CLR bit to enable/disable the power domain
|
||||
* @sta_bit: The SET/CLR STA bit to check for on/off ACK
|
||||
* @caps: The flag for active wake-up action
|
||||
*/
|
||||
struct scpsys_hwv_domain_data {
|
||||
const char *name;
|
||||
u16 set;
|
||||
u16 clr;
|
||||
u16 done;
|
||||
u16 en;
|
||||
u16 set_sta;
|
||||
u16 clr_sta;
|
||||
u8 setclr_bit;
|
||||
u8 sta_bit;
|
||||
u16 caps;
|
||||
};
|
||||
|
||||
struct scpsys_soc_data {
|
||||
const struct scpsys_domain_data *domains_data;
|
||||
int num_domains;
|
||||
const struct scpsys_hwv_domain_data *hwv_domains_data;
|
||||
int num_hwv_domains;
|
||||
enum scpsys_bus_prot_block *bus_prot_blocks;
|
||||
int num_bus_prot_blocks;
|
||||
enum scpsys_mtcmos_type type;
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#define domain_to_rpmhpd(domain) container_of(domain, struct rpmhpd, pd)
|
||||
|
||||
#define RPMH_ARC_MAX_LEVELS 16
|
||||
#define RPMH_ARC_MAX_LEVELS 32
|
||||
|
||||
/**
|
||||
* struct rpmhpd - top level RPMh power domain resource data structure
|
||||
|
|
@ -595,6 +595,31 @@ static const struct rpmhpd_desc sm8750_desc = {
|
|||
.num_pds = ARRAY_SIZE(sm8750_rpmhpds),
|
||||
};
|
||||
|
||||
/* KAANAPALI RPMH powerdomains */
|
||||
static struct rpmhpd *kaanapali_rpmhpds[] = {
|
||||
[RPMHPD_CX] = &cx,
|
||||
[RPMHPD_CX_AO] = &cx_ao,
|
||||
[RPMHPD_EBI] = &ebi,
|
||||
[RPMHPD_GFX] = &gfx,
|
||||
[RPMHPD_GMXC] = &gmxc,
|
||||
[RPMHPD_LCX] = &lcx,
|
||||
[RPMHPD_LMX] = &lmx,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MMCX] = &mmcx,
|
||||
[RPMHPD_MMCX_AO] = &mmcx_ao,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_MXC_AO] = &mxc_ao,
|
||||
[RPMHPD_NSP] = &nsp,
|
||||
[RPMHPD_NSP2] = &nsp2,
|
||||
};
|
||||
|
||||
static const struct rpmhpd_desc kaanapali_desc = {
|
||||
.rpmhpds = kaanapali_rpmhpds,
|
||||
.num_pds = ARRAY_SIZE(kaanapali_rpmhpds),
|
||||
};
|
||||
|
||||
/* QDU1000/QRU1000 RPMH powerdomains */
|
||||
static struct rpmhpd *qdu1000_rpmhpds[] = {
|
||||
[QDU1000_CX] = &cx,
|
||||
|
|
@ -767,6 +792,7 @@ static const struct rpmhpd_desc qcs615_desc = {
|
|||
|
||||
static const struct of_device_id rpmhpd_match_table[] = {
|
||||
{ .compatible = "qcom,glymur-rpmhpd", .data = &glymur_desc },
|
||||
{ .compatible = "qcom,kaanapali-rpmhpd", .data = &kaanapali_desc },
|
||||
{ .compatible = "qcom,milos-rpmhpd", .data = &milos_desc },
|
||||
{ .compatible = "qcom,qcs615-rpmhpd", .data = &qcs615_desc },
|
||||
{ .compatible = "qcom,qcs8300-rpmhpd", .data = &qcs8300_desc },
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <soc/rockchip/rockchip_sip.h>
|
||||
#include <dt-bindings/power/px30-power.h>
|
||||
#include <dt-bindings/power/rockchip,rv1126-power.h>
|
||||
#include <dt-bindings/power/rockchip,rv1126b-power-controller.h>
|
||||
#include <dt-bindings/power/rk3036-power.h>
|
||||
#include <dt-bindings/power/rk3066-power.h>
|
||||
#include <dt-bindings/power/rk3128-power.h>
|
||||
|
|
@ -137,6 +138,20 @@ struct rockchip_pmu {
|
|||
.active_wakeup = wakeup, \
|
||||
}
|
||||
|
||||
#define DOMAIN_M_G(_name, pwr, status, req, idle, ack, g_mask, wakeup, keepon) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.pwr_w_mask = (pwr) << 16, \
|
||||
.pwr_mask = (pwr), \
|
||||
.status_mask = (status), \
|
||||
.req_w_mask = (req) << 16, \
|
||||
.req_mask = (req), \
|
||||
.idle_mask = (idle), \
|
||||
.ack_mask = (ack), \
|
||||
.clk_ungate_mask = (g_mask), \
|
||||
.active_wakeup = wakeup, \
|
||||
}
|
||||
|
||||
#define DOMAIN_M_G_SD(_name, pwr, status, req, idle, ack, g_mask, mem, wakeup, keepon) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
|
|
@ -205,6 +220,9 @@ struct rockchip_pmu {
|
|||
#define DOMAIN_RV1126(name, pwr, req, idle, wakeup) \
|
||||
DOMAIN_M(name, pwr, pwr, req, idle, idle, wakeup)
|
||||
|
||||
#define DOMAIN_RV1126B(name, pwr, req, wakeup) \
|
||||
DOMAIN_M_G(name, pwr, pwr, req, req, req, req, wakeup, true)
|
||||
|
||||
#define DOMAIN_RK3288(name, pwr, status, req, wakeup) \
|
||||
DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup)
|
||||
|
||||
|
|
@ -1104,6 +1122,13 @@ static const struct rockchip_domain_info rv1126_pm_domains[] = {
|
|||
[RV1126_PD_USB] = DOMAIN_RV1126("usb", BIT(9), BIT(15), BIT(15), false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rv1126b_pm_domains[] = {
|
||||
/* name pwr req wakeup */
|
||||
[RV1126B_PD_NPU] = DOMAIN_RV1126B("npu", BIT(0), BIT(8), false),
|
||||
[RV1126B_PD_VDO] = DOMAIN_RV1126B("vdo", BIT(1), BIT(9), false),
|
||||
[RV1126B_PD_AIISP] = DOMAIN_RV1126B("aiisp", BIT(2), BIT(10), false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3036_pm_domains[] = {
|
||||
[RK3036_PD_MSCH] = DOMAIN_RK3036("msch", BIT(14), BIT(23), BIT(30), true),
|
||||
[RK3036_PD_CORE] = DOMAIN_RK3036("core", BIT(13), BIT(17), BIT(24), false),
|
||||
|
|
@ -1516,6 +1541,18 @@ static const struct rockchip_pmu_info rv1126_pmu = {
|
|||
.domain_info = rv1126_pm_domains,
|
||||
};
|
||||
|
||||
static const struct rockchip_pmu_info rv1126b_pmu = {
|
||||
.pwr_offset = 0x210,
|
||||
.status_offset = 0x230,
|
||||
.req_offset = 0x110,
|
||||
.idle_offset = 0x128,
|
||||
.ack_offset = 0x120,
|
||||
.clk_ungate_offset = 0x140,
|
||||
|
||||
.num_domains = ARRAY_SIZE(rv1126b_pm_domains),
|
||||
.domain_info = rv1126b_pm_domains,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_pm_domain_dt_match[] = {
|
||||
{
|
||||
.compatible = "rockchip,px30-power-controller",
|
||||
|
|
@ -1585,6 +1622,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
|
|||
.compatible = "rockchip,rv1126-power-controller",
|
||||
.data = (void *)&rv1126_pmu,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rv1126b-power-controller",
|
||||
.data = (void *)&rv1126b_pmu,
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
|
|||
CI_HDRC_HAS_PORTSC_PEC_MISSED,
|
||||
};
|
||||
|
||||
static const struct ci_hdrc_imx_platform_flag imx95_usb_data = {
|
||||
.flags = CI_HDRC_SUPPORTS_RUNTIME_PM | CI_HDRC_OUT_BAND_WAKEUP,
|
||||
};
|
||||
|
||||
static const struct ci_hdrc_imx_platform_flag s32g_usb_data = {
|
||||
.flags = CI_HDRC_DISABLE_HOST_STREAMING,
|
||||
};
|
||||
|
|
@ -94,6 +98,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
|
|||
{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
|
||||
{ .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
|
||||
{ .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data},
|
||||
{ .compatible = "fsl,imx95-usb", .data = &imx95_usb_data},
|
||||
{ .compatible = "nxp,s32g2-usb", .data = &s32g_usb_data},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
|
@ -704,9 +709,13 @@ static int ci_hdrc_imx_suspend(struct device *dev)
|
|||
|
||||
pinctrl_pm_select_sleep_state(dev);
|
||||
|
||||
if (data->wakeup_irq > 0 && device_may_wakeup(dev))
|
||||
if (data->wakeup_irq > 0 && device_may_wakeup(dev)) {
|
||||
enable_irq_wake(data->wakeup_irq);
|
||||
|
||||
if (data->plat_data->flags & CI_HDRC_OUT_BAND_WAKEUP)
|
||||
device_set_out_band_wakeup(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
|
|
@ -915,6 +916,8 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
dev_pm_domain_detach(&pdev->dev, false);
|
||||
|
||||
return pdev;
|
||||
|
||||
err:
|
||||
|
|
|
|||
|
|
@ -334,10 +334,15 @@ static int dwc3_imx8mp_pm_suspend(struct device *dev)
|
|||
|
||||
ret = dwc3_imx8mp_suspend(dwc3_imx, PMSG_SUSPEND);
|
||||
|
||||
if (device_may_wakeup(dwc3_imx->dev))
|
||||
if (device_may_wakeup(dwc3_imx->dev)) {
|
||||
enable_irq_wake(dwc3_imx->irq);
|
||||
else
|
||||
|
||||
if (device_is_compatible(dev, "fsl,imx95-dwc3"))
|
||||
device_set_out_band_wakeup(dev);
|
||||
|
||||
} else {
|
||||
clk_disable_unprepare(dwc3_imx->suspend_clk);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(dwc3_imx->hsio_clk);
|
||||
dev_dbg(dev, "dwc3 imx8mp pm suspend.\n");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2025 Collabora Ltd
|
||||
* AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_POWER_MT8196_POWER_H
|
||||
#define _DT_BINDINGS_POWER_MT8196_POWER_H
|
||||
|
||||
/* SCPSYS Secure Power Manager - Direct Control */
|
||||
#define MT8196_POWER_DOMAIN_MD 0
|
||||
#define MT8196_POWER_DOMAIN_CONN 1
|
||||
#define MT8196_POWER_DOMAIN_SSUSB_P0 2
|
||||
#define MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0 3
|
||||
#define MT8196_POWER_DOMAIN_SSUSB_P1 4
|
||||
#define MT8196_POWER_DOMAIN_SSUSB_P23 5
|
||||
#define MT8196_POWER_DOMAIN_SSUSB_PHY_P2 6
|
||||
#define MT8196_POWER_DOMAIN_PEXTP_MAC0 7
|
||||
#define MT8196_POWER_DOMAIN_PEXTP_MAC1 8
|
||||
#define MT8196_POWER_DOMAIN_PEXTP_MAC2 9
|
||||
#define MT8196_POWER_DOMAIN_PEXTP_PHY0 10
|
||||
#define MT8196_POWER_DOMAIN_PEXTP_PHY1 11
|
||||
#define MT8196_POWER_DOMAIN_PEXTP_PHY2 12
|
||||
#define MT8196_POWER_DOMAIN_AUDIO 13
|
||||
#define MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT 14
|
||||
#define MT8196_POWER_DOMAIN_ADSP_INFRA 15
|
||||
#define MT8196_POWER_DOMAIN_ADSP_AO 16
|
||||
|
||||
/* SCPSYS Secure Power Manager - HW Voter */
|
||||
#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT 0
|
||||
#define MT8196_POWER_DOMAIN_SSR 1
|
||||
|
||||
/* HFRPSYS MultiMedia Power Control (MMPC) - HW Voter */
|
||||
#define MT8196_POWER_DOMAIN_VDE0 0
|
||||
#define MT8196_POWER_DOMAIN_VDE1 1
|
||||
#define MT8196_POWER_DOMAIN_VDE_VCORE0 2
|
||||
#define MT8196_POWER_DOMAIN_VEN0 3
|
||||
#define MT8196_POWER_DOMAIN_VEN1 4
|
||||
#define MT8196_POWER_DOMAIN_VEN2 5
|
||||
#define MT8196_POWER_DOMAIN_DISP_VCORE 6
|
||||
#define MT8196_POWER_DOMAIN_DIS0_DORMANT 7
|
||||
#define MT8196_POWER_DOMAIN_DIS1_DORMANT 8
|
||||
#define MT8196_POWER_DOMAIN_OVL0_DORMANT 9
|
||||
#define MT8196_POWER_DOMAIN_OVL1_DORMANT 10
|
||||
#define MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT 11
|
||||
#define MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT 12
|
||||
#define MT8196_POWER_DOMAIN_MML0_SHUTDOWN 13
|
||||
#define MT8196_POWER_DOMAIN_MML1_SHUTDOWN 14
|
||||
#define MT8196_POWER_DOMAIN_MM_INFRA0 15
|
||||
#define MT8196_POWER_DOMAIN_MM_INFRA1 16
|
||||
#define MT8196_POWER_DOMAIN_MM_INFRA_AO 17
|
||||
#define MT8196_POWER_DOMAIN_CSI_BS_RX 18
|
||||
#define MT8196_POWER_DOMAIN_CSI_LS_RX 19
|
||||
#define MT8196_POWER_DOMAIN_DSI_PHY0 20
|
||||
#define MT8196_POWER_DOMAIN_DSI_PHY1 21
|
||||
#define MT8196_POWER_DOMAIN_DSI_PHY2 22
|
||||
|
||||
#endif /* _DT_BINDINGS_POWER_MT8196_POWER_H */
|
||||
|
|
@ -33,11 +33,14 @@
|
|||
#define RPMH_REGULATOR_LEVEL_RETENTION 16
|
||||
#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2_1 51
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1_1 54
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_L0 76
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
|
||||
#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
|
||||
#define RPMH_REGULATOR_LEVEL_SVS 128
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
|
||||
* Author: Finley Xiao <finley.xiao@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_POWER_RV1126B_POWER_CONTROLLER_H__
|
||||
#define __DT_BINDINGS_POWER_RV1126B_POWER_CONTROLLER_H__
|
||||
|
||||
/* VD_NPU */
|
||||
#define RV1126B_PD_NPU 0
|
||||
|
||||
/* VD_LOGIC */
|
||||
#define RV1126B_PD_VDO 1
|
||||
#define RV1126B_PD_AIISP 2
|
||||
|
||||
#endif
|
||||
|
|
@ -688,6 +688,7 @@ struct dev_pm_info {
|
|||
bool smart_suspend:1; /* Owned by the PM core */
|
||||
bool must_resume:1; /* Owned by the PM core */
|
||||
bool may_skip_resume:1; /* Set by subsystems */
|
||||
bool out_band_wakeup:1;
|
||||
bool strict_midlayer:1;
|
||||
#else
|
||||
bool should_wakeup:1;
|
||||
|
|
|
|||
|
|
@ -94,6 +94,16 @@ static inline void device_set_wakeup_path(struct device *dev)
|
|||
dev->power.wakeup_path = true;
|
||||
}
|
||||
|
||||
static inline void device_set_out_band_wakeup(struct device *dev)
|
||||
{
|
||||
dev->power.out_band_wakeup = true;
|
||||
}
|
||||
|
||||
static inline bool device_out_band_wakeup(struct device *dev)
|
||||
{
|
||||
return dev->power.out_band_wakeup;
|
||||
}
|
||||
|
||||
/* drivers/base/power/wakeup.c */
|
||||
extern struct wakeup_source *wakeup_source_register(struct device *dev,
|
||||
const char *name);
|
||||
|
|
@ -162,6 +172,13 @@ static inline bool device_wakeup_path(struct device *dev)
|
|||
|
||||
static inline void device_set_wakeup_path(struct device *dev) {}
|
||||
|
||||
static inline void device_set_out_band_wakeup(struct device *dev) {}
|
||||
|
||||
static inline bool device_out_band_wakeup(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void __pm_stay_awake(struct wakeup_source *ws) {}
|
||||
|
||||
static inline void pm_stay_awake(struct device *dev) {}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ int smp_call_function_any(const struct cpumask *mask,
|
|||
|
||||
void kick_all_cpus_sync(void);
|
||||
void wake_up_all_idle_cpus(void);
|
||||
bool cpus_peek_for_pending_ipi(const struct cpumask *mask);
|
||||
|
||||
/*
|
||||
* Generic and arch helpers
|
||||
|
|
@ -216,6 +217,10 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func,
|
|||
|
||||
static inline void kick_all_cpus_sync(void) { }
|
||||
static inline void wake_up_all_idle_cpus(void) { }
|
||||
static inline bool cpus_peek_for_pending_ipi(const struct cpumask *mask)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#define setup_max_cpus 0
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ struct ci_hdrc_platform_data {
|
|||
#define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17)
|
||||
#define CI_HDRC_FORCE_VBUS_ACTIVE_ALWAYS BIT(18)
|
||||
#define CI_HDRC_HAS_SHORT_PKT_LIMIT BIT(19)
|
||||
#define CI_HDRC_OUT_BAND_WAKEUP BIT(20)
|
||||
enum usb_dr_mode dr_mode;
|
||||
#define CI_HDRC_CONTROLLER_RESET_EVENT 0
|
||||
#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
|
||||
|
|
|
|||
22
kernel/smp.c
22
kernel/smp.c
|
|
@ -1087,6 +1087,28 @@ void wake_up_all_idle_cpus(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus);
|
||||
|
||||
/**
|
||||
* cpus_peek_for_pending_ipi - Check for pending IPI for CPUs
|
||||
* @mask: The CPU mask for the CPUs to check.
|
||||
*
|
||||
* This function walks through the @mask to check if there are any pending IPIs
|
||||
* scheduled, for any of the CPUs in the @mask. It does not guarantee
|
||||
* correctness as it only provides a racy snapshot.
|
||||
*
|
||||
* Returns true if there is a pending IPI scheduled and false otherwise.
|
||||
*/
|
||||
bool cpus_peek_for_pending_ipi(const struct cpumask *mask)
|
||||
{
|
||||
unsigned int cpu;
|
||||
|
||||
for_each_cpu(cpu, mask) {
|
||||
if (!llist_empty(per_cpu_ptr(&call_single_queue, cpu)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct smp_call_on_cpu_struct - Call a function on a specific CPU
|
||||
* @work: &work_struct
|
||||
|
|
|
|||
Loading…
Reference in New Issue