mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
pmdomain providers:
- amlogic: Add support for A9 power domains
- bcm: Raise ASB poll timeout to 100us for bcm2835-power
- imx: Allow building power domain drivers as a modules
- mediatek: Add support for the MT6858 power domains
- mediatek: Add support for the MT8196 HFRP DirectCTL power domains
- qcom: Add support for RPMh power domains for Maili
- qcom: Skip retention by default for rpmhpd
- renesas: Add support for R-Car X5H Module Controller
- rockchip: Add a regulator to the RK3568 NPU power domain
- tegra: Add support for multi-socket platforms
-----BEGIN PGP SIGNATURE-----
iQJEBAABCgAuFiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmqC8RYQHHVsZmhAa2Vy
bmVsLm9yZwAKCRD+JoQlc1iMKYloEADS2kGT/z2l2NgivbXZFvz0RSNRG18nIpML
6HwJd0qKr5r+U9mpIkfwvHzI3BQGYWOAt0P8y9Wrf+b32lBoDeZqKAB7N7NSOOB7
FhNHeI+U1BIKoDxjuh/zWlHpwTAIbVDdiEJnBk1uGiG5ydco/CmwaQnDNnJywJfz
dsfiDM1q+okolagNxx+VzhvRaxgSqvGBiX52CAMJmcmiIXIlfNTMKK9rnQRhD3lh
kfhSnZYRQwtl7MQ7990vULYrINxAidU4KIoRnCPSJ+eA7Rl2udtsiEdQYdFba6C5
lzEhHzgDWN9YTExCHFhy/vLOWbehoW/z6Jfz3m/Lxmkv7Zd37t3SuMj/0KnPCrpM
Vtg8ZirqG1hvhihcoUpk20jR7LlUGcX1k5ipsP/ptj8uVkdHKVzen6bHy2FvpMle
bYNRWwd8TKqYxAGsxEMZ59GRpRdIRowFSUAOmcP09b5CI8wslkljpmZWZgBxk1f8
31CpmIDMIIxuYY3m0GR5CHlcAXxZO7N+5kk7AqBgDh1IXKf1/CcvgABetAMcJl07
jcUfBBaZDA64ulzqnAEclW+xjITX5+qONVjEy5D/JORo89ttbYaAKyL10BrAb2lm
WbkAP3R15ueHAKsE9Q6xMZ66V3qJxdF9wqmq3f/4TE+QRntDzvE/KMhCjxG5LOJ4
I1Bb9v3rYA==
=6EOE
-----END PGP SIGNATURE-----
Merge tag 'pmdomain-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm
Pull pmdomain updates from Ulf Hansson:
- amlogic: Add support for A9 power domains
- bcm: Raise ASB poll timeout to 100us for bcm2835-power
- imx: Allow building power domain drivers as a modules
- mediatek:
- Add support for the MT6858 power domains
- Add support for the MT8196 HFRP DirectCTL power domains
- qcom:
- Add support for RPMh power domains for Maili
- Skip retention by default for rpmhpd
- renesas: Add support for R-Car X5H Module Controller
- rockchip: Add a regulator to the RK3568 NPU power domain
- tegra: Add support for multi-socket platforms
* tag 'pmdomain-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (24 commits)
pmdomain: renesas: Add R-Car X5H MDLC driver
dt-bindings: power: Document Renesas R-Car X5H Module Controller
pmdomain: amlogic: Add support for A9 power domains controller
dt-bindings: power: Add Amlogic A9 power domains
clk: imx: imx8qxp: add soft dependency on SCU power domain driver
pmdomain: imx: scu-pd: allow building as a module
of: export of_stdout symbol
pmdomain: imx8m{p,}-blk-ctrl: Add MODULE_DESCRIPTION
pmdomain: mediatek: Add support for MT6858 SoC
pmdomain: mediatek: Add support for secure modem power domain control
dt-bindings: power: Add MediaTek MT6858 power domain controller
pmdomain: rockchip: Add a regulator to the RK3568 NPU power domain
pmdomain: imx: Make IMX8M/IMX9 BLK_CTRL tristate
dt-bindings: power: qcom,rpmpd: document RPMh power domain for Maili
pmdomain: tegra: Add support for multi-socket platforms
pmdomain: bcm: bcm2835-power: Raise ASB poll timeout to 100us
pmdomain: mediatek: Add support for MT8196 HFRP DirectCTL domains
pmdomain: mediatek: Add support for Direct CTL simple power sequence
pmdomain: mediatek: Respect PD relationships during error cleanup
dt-bindings: power: mediatek: Add support for MT8196 direct HFRP
...
This commit is contained in:
commit
ee1b6365f0
|
|
@ -22,6 +22,7 @@ properties:
|
|||
- amlogic,meson-s4-pwrc
|
||||
- amlogic,a4-pwrc
|
||||
- amlogic,a5-pwrc
|
||||
- amlogic,a9-pwrc
|
||||
- amlogic,c3-pwrc
|
||||
- amlogic,t7-pwrc
|
||||
- amlogic,s6-pwrc
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ properties:
|
|||
enum:
|
||||
- mediatek,mt6735-power-controller
|
||||
- mediatek,mt6795-power-controller
|
||||
- mediatek,mt6858-power-controller
|
||||
- mediatek,mt6893-power-controller
|
||||
- mediatek,mt8167-power-controller
|
||||
- mediatek,mt8173-power-controller
|
||||
|
|
@ -34,6 +35,7 @@ properties:
|
|||
- mediatek,mt8189-power-controller
|
||||
- mediatek,mt8192-power-controller
|
||||
- mediatek,mt8195-power-controller
|
||||
- mediatek,mt8196-hfrp-power-controller
|
||||
- mediatek,mt8196-hwv-hfrp-power-controller
|
||||
- mediatek,mt8196-hwv-scp-power-controller
|
||||
- mediatek,mt8196-power-controller
|
||||
|
|
@ -55,7 +57,7 @@ properties:
|
|||
faults while enabling or disabling a power domain.
|
||||
For example, this may hold phandles to INFRACFG and SMI.
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
maxItems: 6
|
||||
|
||||
patternProperties:
|
||||
"^power-domain@[0-9a-f]+$":
|
||||
|
|
@ -102,6 +104,7 @@ $defs:
|
|||
description: |
|
||||
Power domain index. Valid values are defined in:
|
||||
"include/dt-bindings/power/mt6795-power.h" - for MT8167 type power domain.
|
||||
"include/dt-bindings/power/mediatek,mt6858-power.h" - for MT6858 type power domain.
|
||||
"include/dt-bindings/power/mediatek,mt6893-power.h" - for MT6893 type power domain.
|
||||
"include/dt-bindings/power/mt8167-power.h" - for MT8167 type power domain.
|
||||
"include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
|
||||
|
|
@ -155,6 +158,23 @@ required:
|
|||
- compatible
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mediatek,mt6858-power-controller
|
||||
then:
|
||||
properties:
|
||||
access-controllers:
|
||||
items:
|
||||
- description: handle to INFRACFG register block
|
||||
- description: handle to IMG_SUB0 register block
|
||||
- description: handle to CAM_SUB1 register block
|
||||
- description: handle to CAM_SUB0 register block
|
||||
- description: handle to IPE_SUB0 register block
|
||||
- description: handle to VLPCFG register block
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
|
|||
|
|
@ -75,6 +75,10 @@ properties:
|
|||
- enum:
|
||||
- qcom,msm8937-rpmpd
|
||||
- const: qcom,msm8917-rpmpd
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,maili-rpmhpd
|
||||
- const: qcom,hawi-rpmhpd
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/power/renesas,r8a78000-mdlc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas R-Car X5H Module Controller
|
||||
|
||||
maintainers:
|
||||
- Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
|
||||
description:
|
||||
Each instance of the R-Car X5H Module Controller (MODULE CONTROL) provides
|
||||
Power Gating for up to 64 Power Domains, and Module Standby and Reset for up
|
||||
to 256 modules in the Power Domain of each Module hierarchy.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r8a78000-mdlc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
description: |
|
||||
- The first power domain specifier cell is the power domain part, and
|
||||
must be either the Module Power Domain Gating (MPDG) register index
|
||||
(0x00-0x3f) from the datasheet, for power domains which are backed by
|
||||
MPDG bits and which can be controlled in that manner, or a Power
|
||||
Domain number, as defined in
|
||||
<dt-bindings/power/renesas,r8a78000-mdlc.h>, for power domains which
|
||||
are always on, and for which there are no MPDG bits to control them.
|
||||
|
||||
- The second power domain specifier cell is the module standby part, and
|
||||
must be the module number (0x00-0xff), composed of the Module System
|
||||
Reset (MSRES) register index in the high nibble, and the Module Reset
|
||||
Destination bitfield index in the low nibble.
|
||||
const: 2
|
||||
|
||||
'#reset-cells':
|
||||
description:
|
||||
The single reset specifier cell must be the module number (0x00-0xff),
|
||||
and thus identical to the second power domain specifier cell.
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#power-domain-cells'
|
||||
- '#reset-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
system-controller@c3060000 {
|
||||
compatible = "renesas,r8a78000-mdlc";
|
||||
reg = <0xc3060000 0x1000>;
|
||||
#power-domain-cells = <2>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
|
@ -373,3 +373,4 @@ module_exit(imx8qxp_clk_exit);
|
|||
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_SOFTDEP("pre: scu_pd");
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct device_node *of_chosen;
|
|||
EXPORT_SYMBOL(of_chosen);
|
||||
struct device_node *of_aliases;
|
||||
struct device_node *of_stdout;
|
||||
EXPORT_SYMBOL_GPL(of_stdout);
|
||||
static const char *of_stdout_options;
|
||||
|
||||
struct kset *of_kset;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <dt-bindings/power/amlogic,t7-pwrc.h>
|
||||
#include <dt-bindings/power/amlogic,a4-pwrc.h>
|
||||
#include <dt-bindings/power/amlogic,a5-pwrc.h>
|
||||
#include <dt-bindings/power/amlogic,a9-pwrc.h>
|
||||
#include <dt-bindings/power/amlogic,s6-pwrc.h>
|
||||
#include <dt-bindings/power/amlogic,s7-pwrc.h>
|
||||
#include <dt-bindings/power/amlogic,s7d-pwrc.h>
|
||||
|
|
@ -175,6 +176,65 @@ static const struct meson_secure_pwrc_domain_desc a5_pwrc_domains[] = {
|
|||
SEC_PD(A5_DSPA, 0),
|
||||
};
|
||||
|
||||
static const struct meson_secure_pwrc_domain_desc a9_pwrc_domains[] = {
|
||||
SEC_PD(A9_DSPA, 0),
|
||||
SEC_PD(A9_U3HSG_U3, 0),
|
||||
SEC_PD(A9_DP, 0),
|
||||
SEC_PD(A9_DOS_HCODEC, 0),
|
||||
SEC_PD(A9_TAHOE, 0),
|
||||
SEC_PD(A9_DOS_HEVC, 0),
|
||||
SEC_PD(A9_U2H, 0),
|
||||
SEC_PD(A9_U3DRD_B, 0),
|
||||
SEC_PD(A9_VPU_HDMI, 0),
|
||||
SEC_PD(A9_U2DRD, 0),
|
||||
SEC_PD(A9_U3DRD_A, 0),
|
||||
SEC_PD(A9_SD_EMMC_C, 0),
|
||||
SEC_PD(A9_GE2D, 0),
|
||||
SEC_PD(A9_AMFC, 0),
|
||||
SEC_PD(A9_EDPTX, 0),
|
||||
SEC_PD(A9_OPP, 0),
|
||||
SEC_PD(A9_VICP, 0),
|
||||
SEC_PD(A9_SD_EMMC_A, 0),
|
||||
SEC_PD(A9_SD_EMMC_B, 0),
|
||||
SEC_PD(A9_ETH, 0),
|
||||
SEC_PD(A9_PCIE_A, 0),
|
||||
SEC_PD(A9_PCIE_B, 0),
|
||||
SEC_PD(A9_NNA_4T, 0),
|
||||
SEC_PD(A9_HDMIRX, 0),
|
||||
SEC_PD(A9_CVE, 0),
|
||||
SEC_PD(A9_ISP, 0),
|
||||
SEC_PD(A9_ETH_1G, 0),
|
||||
SEC_PD(A9_U3HSG_HSG, 0),
|
||||
SEC_PD(A9_U3DPPHY_U3, 0),
|
||||
SEC_PD(A9_U3DPPHY_DP, 0),
|
||||
SEC_PD(A9_PCIE3PHY, 0),
|
||||
SEC_PD(A9_U3HSG_PCIE2, 0),
|
||||
SEC_PD(A9_MALI_TOP, 0),
|
||||
SEC_PD(A9_AO_SED, 0),
|
||||
SEC_PD(A9_AO_IR, 0),
|
||||
/* UART_B is for console log, and should be always on */
|
||||
SEC_PD(A9_AO_UART_B, GENPD_FLAG_ALWAYS_ON),
|
||||
SEC_PD(A9_AO_UART_C, 0),
|
||||
SEC_PD(A9_AO_UART_D, 0),
|
||||
SEC_PD(A9_AO_SPISG, 0),
|
||||
SEC_PD(A9_AO_UART_E, 0),
|
||||
SEC_PD(A9_AO_CEC, 0),
|
||||
/* SRAMA is used as ATF runtime memory, and should be always on */
|
||||
SEC_PD(A9_EE_SRAMA, GENPD_FLAG_ALWAYS_ON),
|
||||
SEC_PD(A9_AUDIO, 0),
|
||||
/* DMC0 is for DDR PHY ana/dig and DMC, and should be always on */
|
||||
SEC_PD(A9_DMC0, GENPD_FLAG_ALWAYS_ON),
|
||||
/*GIC needs to be used consistently, and should be always on */
|
||||
SEC_PD(A9_GIC, GENPD_FLAG_ALWAYS_ON),
|
||||
/* DDRPHY is for DDR Work, and should be always on */
|
||||
SEC_PD(A9_DDRPHY, GENPD_FLAG_ALWAYS_ON),
|
||||
SEC_PD(A9_AUCPU, 0),
|
||||
SEC_PD(A9_DSI0, 0),
|
||||
SEC_PD(A9_DSI1, 0),
|
||||
SEC_PD(A9_CAN0, 0),
|
||||
SEC_PD(A9_CAN1, 0),
|
||||
};
|
||||
|
||||
static const struct meson_secure_pwrc_domain_desc c3_pwrc_domains[] = {
|
||||
SEC_PD(C3_NNA, 0),
|
||||
SEC_PD(C3_AUDIO, 0),
|
||||
|
|
@ -425,6 +485,11 @@ static const struct meson_secure_pwrc_domain_data amlogic_secure_a5_pwrc_data =
|
|||
.count = ARRAY_SIZE(a5_pwrc_domains),
|
||||
};
|
||||
|
||||
static const struct meson_secure_pwrc_domain_data amlogic_secure_a9_pwrc_data = {
|
||||
.domains = a9_pwrc_domains,
|
||||
.count = ARRAY_SIZE(a9_pwrc_domains),
|
||||
};
|
||||
|
||||
static const struct meson_secure_pwrc_domain_data amlogic_secure_c3_pwrc_data = {
|
||||
.domains = c3_pwrc_domains,
|
||||
.count = ARRAY_SIZE(c3_pwrc_domains),
|
||||
|
|
@ -468,6 +533,10 @@ static const struct of_device_id meson_secure_pwrc_match_table[] = {
|
|||
.compatible = "amlogic,a5-pwrc",
|
||||
.data = &amlogic_secure_a5_pwrc_data,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic,a9-pwrc",
|
||||
.data = &amlogic_secure_a9_pwrc_data,
|
||||
},
|
||||
{
|
||||
.compatible = "amlogic,c3-pwrc",
|
||||
.data = &amlogic_secure_c3_pwrc_data,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ config ARM_SCMI_POWER_DOMAIN
|
|||
enabled or disabled via the SCP firmware
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called scmi_pm_domain. Note this may needed early in boot
|
||||
will be called scmi_pm_domain. Note this may be needed early in boot
|
||||
before rootfs may be available.
|
||||
|
||||
config ARM_SCPI_POWER_DOMAIN
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ static int bcm2835_asb_control(struct bcm2835_power *power, u32 reg, bool enable
|
|||
writel(PM_PASSWORD | val, base + reg);
|
||||
|
||||
if (readl_poll_timeout_atomic(base + reg, val,
|
||||
!!(val & ASB_ACK) != enable, 0, 5))
|
||||
!!(val & ASB_ACK) != enable, 0, 100))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
|
|
@ -677,7 +677,12 @@ static int bcm2835_power_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate);
|
||||
ret = of_genpd_add_provider_onecell(dev->parent->of_node,
|
||||
&power->pd_xlate);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "failed to add genpd provider\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev_info(dev, "Broadcom BCM2835 power domains driver");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -10,18 +10,21 @@ config IMX_GPCV2_PM_DOMAINS
|
|||
default y if SOC_IMX7D
|
||||
|
||||
config IMX8M_BLK_CTRL
|
||||
bool
|
||||
default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
|
||||
tristate "i.MX8M BLK CTRL driver"
|
||||
depends on SOC_IMX8M
|
||||
depends on IMX_GPCV2_PM_DOMAINS
|
||||
depends on PM_GENERIC_DOMAINS
|
||||
depends on COMMON_CLK
|
||||
default y
|
||||
|
||||
config IMX9_BLK_CTRL
|
||||
bool
|
||||
default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
|
||||
tristate "i.MX93 BLK CTRL driver"
|
||||
depends on SOC_IMX9
|
||||
depends on PM_GENERIC_DOMAINS
|
||||
default y
|
||||
|
||||
config IMX_SCU_PD
|
||||
bool "IMX SCU Power Domain driver"
|
||||
tristate "IMX SCU Power Domain driver"
|
||||
depends on IMX_SCU
|
||||
help
|
||||
The System Controller Firmware (SCFW) based power domain driver.
|
||||
|
|
|
|||
|
|
@ -953,4 +953,5 @@ static struct platform_driver imx8m_blk_ctrl_driver = {
|
|||
},
|
||||
};
|
||||
module_platform_driver(imx8m_blk_ctrl_driver);
|
||||
MODULE_DESCRIPTION("NXP i.MX8M power domain driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -890,4 +890,5 @@ static struct platform_driver imx8mp_blk_ctrl_driver = {
|
|||
},
|
||||
};
|
||||
module_platform_driver(imx8mp_blk_ctrl_driver);
|
||||
MODULE_DESCRIPTION("NXP i.MX8MP power domain driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ static const struct of_device_id imx_sc_pd_match[] = {
|
|||
{ .compatible = "fsl,scu-pd", &imx8qxp_scu_pd},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_sc_pd_match);
|
||||
|
||||
static struct platform_driver imx_sc_pd_driver = {
|
||||
.driver = {
|
||||
|
|
@ -540,7 +541,12 @@ static struct platform_driver imx_sc_pd_driver = {
|
|||
},
|
||||
.probe = imx_sc_pd_probe,
|
||||
};
|
||||
builtin_platform_driver(imx_sc_pd_driver);
|
||||
|
||||
static int __init imx_sc_pd_driver_init(void)
|
||||
{
|
||||
return platform_driver_register(&imx_sc_pd_driver);
|
||||
}
|
||||
subsys_initcall(imx_sc_pd_driver_init);
|
||||
|
||||
MODULE_AUTHOR("Dong Aisheng <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("IMX SCU Power Domain driver");
|
||||
|
|
|
|||
466
drivers/pmdomain/mediatek/mt6858-pm-domains.h
Normal file
466
drivers/pmdomain/mediatek/mt6858-pm-domains.h
Normal file
|
|
@ -0,0 +1,466 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2025 MediaTek Inc.
|
||||
* KY Liu <ky.liu@mediatek.com>
|
||||
* Copyright (c) 2026 Jolla Mobile Ltd
|
||||
* Nikolai Burov <nikolai.burov@jolla.com>
|
||||
*/
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT6858_PM_DOMAINS_H
|
||||
#define __SOC_MEDIATEK_MT6858_PM_DOMAINS_H
|
||||
|
||||
#include "mtk-pm-domains.h"
|
||||
#include <dt-bindings/power/mediatek,mt6858-power.h>
|
||||
|
||||
/* TOP_AXI registers */
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET 0x0c14
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR 0x0c18
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY 0x0c1c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_DIS0 (BIT(0) | BIT(1) | BIT(18))
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_ISP_IPE BIT(2)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_ISP_IMG1 BIT(3)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_VEN0 BIT(12)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_VDE0 BIT(20)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CAM_MAIN (BIT(30) | BIT(31))
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET 0x0c24
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR 0x0c28
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY 0x0c2c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_ISP_IMG1 BIT(7)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_ISP_IPE BIT(8)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CAM_MAIN (BIT(9) | BIT(10))
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_VEN0 BIT(12)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_VDE0 BIT(13)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_MM_INFRA (GENMASK(3, 1) | BIT(6))
|
||||
#define MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_MM_INFRA_2ND (BIT(0) | BIT(5) | GENMASK(15, 7))
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_SET 0x0c44
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_CLR 0x0c48
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_RDY 0x0c4c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_CONN BIT(8)
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_MM_INFRA BIT(16)
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_SET 0x0c54
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_CLR 0x0c58
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_RDY 0x0c5c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_MM_INFRA BIT(11)
|
||||
#define MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_CONN BIT(12)
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_SET 0x0c64
|
||||
#define MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_CLR 0x0c68
|
||||
#define MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_RDY 0x0c6c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_MM_INFRA (BIT(20) | BIT(21))
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_SET 0x0c84
|
||||
#define MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_CLR 0x0c88
|
||||
#define MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_RDY 0x0c8c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_AUDIO BIT(6)
|
||||
#define MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_SSUSB BIT(7)
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_MCU_STA_0_SET 0x0c94
|
||||
#define MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CLR 0x0c98
|
||||
#define MT6858_TOP_AXI_PROT_EN_MCU_STA_0_RDY 0x0c9c
|
||||
|
||||
#define MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CONN BIT(1)
|
||||
#define MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CONN_2ND BIT(0)
|
||||
|
||||
/* {IMG,IPE,CAM}_SUBx registers */
|
||||
#define MT6858_SUBx_PROT_EN_SET 0x03c4
|
||||
#define MT6858_SUBx_PROT_EN_CLR 0x03c8
|
||||
#define MT6858_SUBx_PROT_EN_STA 0x03cc
|
||||
|
||||
#define MT6858_IMG_SUB0_PROT_EN_SMI_ISP_IMG1 (BIT(0) | BIT(1))
|
||||
|
||||
#define MT6858_IPE_SUB0_PROT_EN_SMI_ISP_IPE (BIT(0) | BIT(1))
|
||||
|
||||
#define MT6858_CAM_SUB0_PROT_EN_SMI_CAM_MAIN BIT(0)
|
||||
#define MT6858_CAM_SUB0_PROT_EN_SMI_CAM_SUBB BIT(1)
|
||||
|
||||
#define MT6858_CAM_SUB1_PROT_EN_SMI_CAM_MAIN BIT(0)
|
||||
#define MT6858_CAM_SUB1_PROT_EN_SMI_CAM_SUBA BIT(1)
|
||||
|
||||
/* VLP_AXI registers */
|
||||
#define MT6858_VLP_AXI_PROT_EN_SET 0x0214
|
||||
#define MT6858_VLP_AXI_PROT_EN_CLR 0x0218
|
||||
#define MT6858_VLP_AXI_PROT_EN_STA 0x021c
|
||||
|
||||
#define MT6858_VLP_AXI_PROT_EN_MM_PROC BIT(8)
|
||||
#define MT6858_VLP_AXI_PROT_EN_MM_PROC_2ND (BIT(9) | BIT(10))
|
||||
|
||||
/* PWR_CON registers */
|
||||
#define MT6858_PWR_ACK BIT(30)
|
||||
#define MT6858_PWR_ACK_2ND BIT(31)
|
||||
|
||||
static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt6858[] = {
|
||||
BUS_PROT_BLOCK_INFRA,
|
||||
BUS_PROT_BLOCK_IMG_SUB0,
|
||||
BUS_PROT_BLOCK_CAM_SUB1,
|
||||
BUS_PROT_BLOCK_CAM_SUB0,
|
||||
BUS_PROT_BLOCK_IPE_SUB0,
|
||||
BUS_PROT_BLOCK_VLP,
|
||||
};
|
||||
|
||||
static const struct scpsys_domain_data scpsys_domain_data_mt6858[] = {
|
||||
[MT6858_POWER_DOMAIN_MD] = {
|
||||
.name = "md",
|
||||
/*
|
||||
* Note: the PWR_ACK_2ND bit is not used for the modem domain.
|
||||
* Skip it and fall back to checking the 1st bit twice.
|
||||
*/
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.ctl_offs = 0xe00,
|
||||
.pwr_sta_offs = 0xe00,
|
||||
.pwr_sta2nd_offs = 0xe00,
|
||||
.ext_buck_iso_offs = 0xf20,
|
||||
.ext_buck_iso_mask = GENMASK(1, 0),
|
||||
.caps = MTK_SCPD_MODEM_SECURE_PWRSEQ | MTK_SCPD_EXT_BUCK_ISO |
|
||||
MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_CONN] = {
|
||||
.name = "conn",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe04,
|
||||
.pwr_sta_offs = 0xe04,
|
||||
.pwr_sta2nd_offs = 0xe04,
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CONN,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_CONN,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CONN_2ND,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MCU_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_CONN,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_RDY),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_AUDIO] = {
|
||||
.name = "audio",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe18,
|
||||
.pwr_sta_offs = 0xe18,
|
||||
.pwr_sta2nd_offs = 0xe18,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_AUDIO,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_RDY),
|
||||
},
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_ISP_IMG1] = {
|
||||
.name = "isp-img1",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_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(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_ISP_IMG1,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_ISP_IMG1,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(IMG_SUB0,
|
||||
MT6858_IMG_SUB0_PROT_EN_SMI_ISP_IMG1,
|
||||
MT6858_SUBx_PROT_EN_SET,
|
||||
MT6858_SUBx_PROT_EN_CLR,
|
||||
MT6858_SUBx_PROT_EN_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_ISP_IMG2] = {
|
||||
.name = "isp-img2",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe2c,
|
||||
.pwr_sta_offs = 0xe2c,
|
||||
.pwr_sta2nd_offs = 0xe2c,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_ISP_IPE] = {
|
||||
.name = "isp-ipe",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe30,
|
||||
.pwr_sta_offs = 0xe30,
|
||||
.pwr_sta2nd_offs = 0xe30,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_ISP_IPE,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_ISP_IPE,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(IPE_SUB0,
|
||||
MT6858_IPE_SUB0_PROT_EN_SMI_ISP_IPE,
|
||||
MT6858_SUBx_PROT_EN_SET,
|
||||
MT6858_SUBx_PROT_EN_CLR,
|
||||
MT6858_SUBx_PROT_EN_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_VDE0] = {
|
||||
.name = "vde0",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_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(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_VDE0,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_VDE0,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
},
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_VEN0] = {
|
||||
.name = "ven0",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_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(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_VEN0,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_VEN0,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
},
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_CAM_MAIN] = {
|
||||
.name = "cam-main",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe44,
|
||||
.pwr_sta_offs = 0xe44,
|
||||
.pwr_sta2nd_offs = 0xe44,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CAM_MAIN,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CAM_MAIN,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(CAM_SUB0,
|
||||
MT6858_CAM_SUB0_PROT_EN_SMI_CAM_MAIN,
|
||||
MT6858_SUBx_PROT_EN_SET,
|
||||
MT6858_SUBx_PROT_EN_CLR,
|
||||
MT6858_SUBx_PROT_EN_STA),
|
||||
BUS_PROT_WR_IGN(CAM_SUB1,
|
||||
MT6858_CAM_SUB1_PROT_EN_SMI_CAM_MAIN,
|
||||
MT6858_SUBx_PROT_EN_SET,
|
||||
MT6858_SUBx_PROT_EN_CLR,
|
||||
MT6858_SUBx_PROT_EN_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_CAM_SUBA] = {
|
||||
.name = "cam-suba",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_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(CAM_SUB1,
|
||||
MT6858_CAM_SUB1_PROT_EN_SMI_CAM_SUBA,
|
||||
MT6858_SUBx_PROT_EN_SET,
|
||||
MT6858_SUBx_PROT_EN_CLR,
|
||||
MT6858_SUBx_PROT_EN_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_CAM_SUBB] = {
|
||||
.name = "cam-subb",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe50,
|
||||
.pwr_sta_offs = 0xe50,
|
||||
.pwr_sta2nd_offs = 0xe50,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(CAM_SUB0,
|
||||
MT6858_CAM_SUB0_PROT_EN_SMI_CAM_SUBB,
|
||||
MT6858_SUBx_PROT_EN_SET,
|
||||
MT6858_SUBx_PROT_EN_CLR,
|
||||
MT6858_SUBx_PROT_EN_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_DIS0] = {
|
||||
.name = "dis0",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe6c,
|
||||
.pwr_sta_offs = 0xe6c,
|
||||
.pwr_sta2nd_offs = 0xe6c,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_DIS0,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_0_RDY),
|
||||
},
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_MM_INFRA] = {
|
||||
.name = "mm-infra",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe74,
|
||||
.pwr_sta_offs = 0xe74,
|
||||
.pwr_sta2nd_offs = 0xe74,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_MM_INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_MM_INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_MM_INFRA_2ND,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_MMSYS_STA_1_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_MM_INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_INFRASYS_STA_0_RDY),
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_MM_INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_EMISYS_STA_0_RDY),
|
||||
},
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_MM_PROC_DORMANT] = {
|
||||
.name = "mm-proc-dormant",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe78,
|
||||
.pwr_sta_offs = 0xe78,
|
||||
.pwr_sta2nd_offs = 0xe78,
|
||||
.sram_pdn_bits = BIT(9),
|
||||
.sram_pdn_ack_bits = BIT(13),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(VLP,
|
||||
MT6858_VLP_AXI_PROT_EN_MM_PROC,
|
||||
MT6858_VLP_AXI_PROT_EN_SET,
|
||||
MT6858_VLP_AXI_PROT_EN_CLR,
|
||||
MT6858_VLP_AXI_PROT_EN_STA),
|
||||
BUS_PROT_WR_IGN(VLP,
|
||||
MT6858_VLP_AXI_PROT_EN_MM_PROC_2ND,
|
||||
MT6858_VLP_AXI_PROT_EN_SET,
|
||||
MT6858_VLP_AXI_PROT_EN_CLR,
|
||||
MT6858_VLP_AXI_PROT_EN_STA),
|
||||
},
|
||||
.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_SRAM_PDN_INVERTED,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_CSI_RX] = {
|
||||
.name = "csi-rx",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xe98,
|
||||
.pwr_sta_offs = 0xe98,
|
||||
.pwr_sta2nd_offs = 0xe98,
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT6858_POWER_DOMAIN_SSUSB] = {
|
||||
.name = "ssusb",
|
||||
.sta_mask = MT6858_PWR_ACK,
|
||||
.sta2nd_mask = MT6858_PWR_ACK_2ND,
|
||||
.ctl_offs = 0xea4,
|
||||
.pwr_sta_offs = 0xea4,
|
||||
.pwr_sta2nd_offs = 0xea4,
|
||||
.sram_pdn_bits = BIT(8),
|
||||
.sram_pdn_ack_bits = BIT(12),
|
||||
.bp_cfg = {
|
||||
BUS_PROT_WR_IGN(INFRA,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_SSUSB,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_SET,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_CLR,
|
||||
MT6858_TOP_AXI_PROT_EN_PERISYS_STA_0_RDY),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt6858_scpsys_data = {
|
||||
.domains_data = scpsys_domain_data_mt6858,
|
||||
.num_domains = ARRAY_SIZE(scpsys_domain_data_mt6858),
|
||||
.bus_prot_blocks = scpsys_bus_prot_blocks_mt6858,
|
||||
.num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt6858),
|
||||
.type = SCPSYS_MTCMOS_TYPE_DIRECT_CTL,
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT6858_PM_DOMAINS_H */
|
||||
|
|
@ -602,6 +602,27 @@ static const struct scpsys_hwv_domain_data hfrpsys_hwv_domain_data_mt8196[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_domain_data hfrpsys_domain_data_mt8196[] = {
|
||||
[MT8196_POWER_DOMAIN_EDPTX] = {
|
||||
.name = "edp-tx",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0x74,
|
||||
.pwr_sta_offs = 0x74,
|
||||
.pwr_sta2nd_offs = 0x74,
|
||||
.caps = MTK_SCPD_SIMPLE_PWRSEQ,
|
||||
},
|
||||
[MT8196_POWER_DOMAIN_DPTX] = {
|
||||
.name = "dp-tx",
|
||||
.sta_mask = MT8196_PWR_ACK,
|
||||
.sta2nd_mask = MT8196_PWR_ACK_2ND,
|
||||
.ctl_offs = 0x78,
|
||||
.pwr_sta_offs = 0x78,
|
||||
.pwr_sta2nd_offs = 0x78,
|
||||
.caps = MTK_SCPD_SIMPLE_PWRSEQ,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8196_scpsys_data = {
|
||||
.domains_data = scpsys_domain_data_mt8196,
|
||||
.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8196),
|
||||
|
|
@ -616,6 +637,12 @@ static const struct scpsys_soc_data mt8196_scpsys_hwv_data = {
|
|||
.type = SCPSYS_MTCMOS_TYPE_HW_VOTER,
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8196_hfrpsys_data = {
|
||||
.domains_data = hfrpsys_domain_data_mt8196,
|
||||
.num_domains = ARRAY_SIZE(hfrpsys_domain_data_mt8196),
|
||||
.type = SCPSYS_MTCMOS_TYPE_DIRECT_CTL,
|
||||
};
|
||||
|
||||
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),
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "mt6735-pm-domains.h"
|
||||
#include "mt6795-pm-domains.h"
|
||||
#include "mt6858-pm-domains.h"
|
||||
#include "mt6893-pm-domains.h"
|
||||
#include "mt8167-pm-domains.h"
|
||||
#include "mt8173-pm-domains.h"
|
||||
|
|
@ -57,6 +58,10 @@
|
|||
|
||||
#define MTK_SIP_KERNEL_HWCCF_CONTROL MTK_SIP_SMC_CMD(0x540)
|
||||
|
||||
/* Secure MTCMOS commands for modem subsystem */
|
||||
#define MTK_MD_MTCMOS_ENABLE 18
|
||||
#define MTK_MD_MTCMOS_DISABLE 19
|
||||
|
||||
struct scpsys_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
const struct scpsys_domain_data *data;
|
||||
|
|
@ -547,9 +552,11 @@ static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void scpsys_ctl_pwrseq_off(struct scpsys_domain *pd)
|
||||
static int scpsys_ctl_pwrseq_off(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
||||
switch (pd->data->rtff_type) {
|
||||
case SCPSYS_RTFF_TYPE_GENERIC:
|
||||
|
|
@ -581,6 +588,41 @@ static void scpsys_ctl_pwrseq_off(struct scpsys_domain *pd)
|
|||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
|
||||
|
||||
/* wait until PWR_ACK = 0 */
|
||||
ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US,
|
||||
MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_simple_pwrseq_on(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
|
||||
/* Enable subsys clock input and trigger power domain reset state */
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
|
||||
/* Wait for the hardware to stabilize */
|
||||
udelay(1);
|
||||
|
||||
/* Get out of reset: set power on */
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_simple_pwrseq_off(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_modem_pwrseq_on(struct scpsys_domain *pd)
|
||||
|
|
@ -603,14 +645,52 @@ static int scpsys_modem_pwrseq_on(struct scpsys_domain *pd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void scpsys_modem_pwrseq_off(struct scpsys_domain *pd)
|
||||
static int scpsys_modem_pwrseq_off(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
|
||||
|
||||
if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B))
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
|
||||
/* wait until PWR_ACK = 0 */
|
||||
ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US,
|
||||
MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool scpsys_modem_sec_poll(unsigned long cmd)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
|
||||
arm_smccc_smc(MTK_SIP_KERNEL_CCCI_CONTROL, cmd, 1, 0, 0, 0, 0, 0, &res);
|
||||
|
||||
return res.a0 == 0;
|
||||
}
|
||||
|
||||
static int scpsys_modem_sec_power_on(bool on)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
unsigned long cmd = on ? MTK_MD_MTCMOS_ENABLE : MTK_MD_MTCMOS_DISABLE;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
||||
arm_smccc_smc(MTK_SIP_KERNEL_CCCI_CONTROL, cmd, 0, 0, 0, 0, 0, 0, &res);
|
||||
if (res.a0 == 0)
|
||||
return 0;
|
||||
|
||||
ret = readx_poll_timeout(scpsys_modem_sec_poll, cmd, tmp, tmp,
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_power_on(struct generic_pm_domain *genpd)
|
||||
|
|
@ -631,8 +711,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
regmap_clear_bits(scpsys->base, pd->data->ext_buck_iso_offs,
|
||||
pd->data->ext_buck_iso_mask);
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_SECURE_PWRSEQ))
|
||||
ret = scpsys_modem_sec_power_on(true);
|
||||
else if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
|
||||
ret = scpsys_modem_pwrseq_on(pd);
|
||||
else if (MTK_SCPD_CAPS(pd, MTK_SCPD_SIMPLE_PWRSEQ))
|
||||
ret = scpsys_simple_pwrseq_on(pd);
|
||||
else
|
||||
ret = scpsys_ctl_pwrseq_on(pd);
|
||||
|
||||
|
|
@ -660,9 +744,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
goto err_pwr_ack;
|
||||
}
|
||||
|
||||
ret = scpsys_sram_enable(pd);
|
||||
if (ret < 0)
|
||||
goto err_disable_subsys_clks;
|
||||
if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SIMPLE_PWRSEQ) &&
|
||||
!MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_SECURE_PWRSEQ)) {
|
||||
ret = scpsys_sram_enable(pd);
|
||||
if (ret < 0)
|
||||
goto err_disable_subsys_clks;
|
||||
}
|
||||
|
||||
ret = scpsys_bus_protect_disable(pd, 0);
|
||||
if (ret < 0)
|
||||
|
|
@ -680,7 +767,9 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
err_enable_bus_protect:
|
||||
scpsys_bus_protect_enable(pd, 0);
|
||||
err_disable_sram:
|
||||
scpsys_sram_disable(pd);
|
||||
if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SIMPLE_PWRSEQ) &&
|
||||
!MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_SECURE_PWRSEQ))
|
||||
scpsys_sram_disable(pd);
|
||||
err_disable_subsys_clks:
|
||||
if (!MTK_SCPD_CAPS(pd, MTK_SCPD_STRICT_BUS_PROTECTION))
|
||||
clk_bulk_disable_unprepare(pd->num_subsys_clks,
|
||||
|
|
@ -695,16 +784,21 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
|
|||
static int scpsys_power_off_internal(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
||||
ret = scpsys_bus_protect_enable(pd, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = scpsys_sram_disable(pd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_SECURE_PWRSEQ)) {
|
||||
ret = scpsys_modem_sec_power_on(false);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SIMPLE_PWRSEQ)) {
|
||||
ret = scpsys_sram_disable(pd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pd->data->ext_buck_iso_offs && MTK_SCPD_CAPS(pd, MTK_SCPD_EXT_BUCK_ISO))
|
||||
regmap_set_bits(scpsys->base, pd->data->ext_buck_iso_offs,
|
||||
|
|
@ -717,15 +811,21 @@ static int scpsys_power_off_internal(struct scpsys_domain *pd)
|
|||
return ret;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
|
||||
scpsys_modem_pwrseq_off(pd);
|
||||
else
|
||||
scpsys_ctl_pwrseq_off(pd);
|
||||
ret = scpsys_modem_pwrseq_off(pd);
|
||||
else if (MTK_SCPD_CAPS(pd, MTK_SCPD_SIMPLE_PWRSEQ))
|
||||
ret = scpsys_simple_pwrseq_off(pd);
|
||||
else if (!MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_SECURE_PWRSEQ))
|
||||
ret = scpsys_ctl_pwrseq_off(pd);
|
||||
|
||||
if (ret < 0) {
|
||||
/* Re-enable clocks so that next power off doesn't break the refcount */
|
||||
int r = clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks);
|
||||
|
||||
if (r)
|
||||
dev_warn(scpsys->dev, "Could not re-enable clocks: %d\n", r);
|
||||
|
||||
/* wait until PWR_ACK = 0 */
|
||||
ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US,
|
||||
MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
clk_bulk_disable_unprepare(pd->num_clks, pd->clks);
|
||||
|
||||
|
|
@ -742,7 +842,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
|
|||
}
|
||||
|
||||
static struct
|
||||
generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node)
|
||||
generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node,
|
||||
u8 *domains_idx, u8 *num_domains)
|
||||
{
|
||||
const struct scpsys_domain_data *domain_data;
|
||||
const struct scpsys_hwv_domain_data *hwv_domain_data;
|
||||
|
|
@ -917,6 +1018,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
else
|
||||
pm_genpd_init(&pd->genpd, NULL, false);
|
||||
|
||||
domains_idx[(*num_domains)++] = (u8) id;
|
||||
scpsys->domains[id] = &pd->genpd;
|
||||
|
||||
return scpsys->pd_data.domains[id];
|
||||
|
|
@ -928,7 +1030,8 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *parent)
|
||||
static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *parent,
|
||||
u8 *domains_idx, u8 *num_domains)
|
||||
{
|
||||
struct generic_pm_domain *child_pd, *parent_pd;
|
||||
struct device_node *child;
|
||||
|
|
@ -951,7 +1054,7 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren
|
|||
|
||||
parent_pd = scpsys->pd_data.domains[id];
|
||||
|
||||
child_pd = scpsys_add_one_domain(scpsys, child);
|
||||
child_pd = scpsys_add_one_domain(scpsys, child, domains_idx, num_domains);
|
||||
if (IS_ERR(child_pd)) {
|
||||
ret = PTR_ERR(child_pd);
|
||||
dev_err_probe(scpsys->dev, ret, "%pOF: failed to get child domain id\n",
|
||||
|
|
@ -960,7 +1063,7 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren
|
|||
}
|
||||
|
||||
/* recursive call to add all subdomains */
|
||||
ret = scpsys_add_subdomain(scpsys, child);
|
||||
ret = scpsys_add_subdomain(scpsys, child, domains_idx, num_domains);
|
||||
if (ret)
|
||||
goto err_put_node;
|
||||
|
||||
|
|
@ -1001,7 +1104,7 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd)
|
|||
if (scpsys_hwv_domain_is_enable_done(pd))
|
||||
scpsys_hwv_power_off_internal(pd);
|
||||
} else {
|
||||
if (scpsys_domain_is_on(pd))
|
||||
if (scpsys_domain_is_on(pd) || MTK_SCPD_CAPS(pd, MTK_SCPD_SIMPLE_PWRSEQ))
|
||||
scpsys_power_off_internal(pd);
|
||||
}
|
||||
|
||||
|
|
@ -1009,14 +1112,16 @@ static void scpsys_remove_one_domain(struct scpsys_domain *pd)
|
|||
clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks);
|
||||
}
|
||||
|
||||
static void scpsys_domain_cleanup(struct scpsys *scpsys)
|
||||
static void scpsys_domain_cleanup(struct scpsys *scpsys, u8 *domains_idx, u8 num_probed)
|
||||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
struct scpsys_domain *pd;
|
||||
int i;
|
||||
|
||||
for (i = scpsys->pd_data.num_domains - 1; i >= 0; i--) {
|
||||
genpd = scpsys->pd_data.domains[i];
|
||||
for (i = num_probed - 1; i >= 0; i--) {
|
||||
u8 pd_idx = domains_idx[i];
|
||||
|
||||
genpd = scpsys->pd_data.domains[pd_idx];
|
||||
if (genpd) {
|
||||
pd = to_scpsys_domain(genpd);
|
||||
scpsys_remove_one_domain(pd);
|
||||
|
|
@ -1104,6 +1209,12 @@ static int scpsys_get_bus_protection_legacy(struct device *dev, struct scpsys *s
|
|||
regmap[2] = NULL;
|
||||
}
|
||||
|
||||
/* If no access controllers are needed, don't allocate and don't fail */
|
||||
if (num_regmaps == 0) {
|
||||
scpsys->bus_prot = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
scpsys->bus_prot = devm_kmalloc_array(dev, num_regmaps,
|
||||
sizeof(*scpsys->bus_prot), GFP_KERNEL);
|
||||
if (!scpsys->bus_prot)
|
||||
|
|
@ -1178,6 +1289,10 @@ static const struct of_device_id scpsys_of_match[] = {
|
|||
.compatible = "mediatek,mt6795-power-controller",
|
||||
.data = &mt6795_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt6858-power-controller",
|
||||
.data = &mt6858_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt6893-power-controller",
|
||||
.data = &mt6893_scpsys_data,
|
||||
|
|
@ -1218,6 +1333,10 @@ static const struct of_device_id scpsys_of_match[] = {
|
|||
.compatible = "mediatek,mt8196-power-controller",
|
||||
.data = &mt8196_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8196-hfrp-power-controller",
|
||||
.data = &mt8196_hfrpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8196-hwv-hfrp-power-controller",
|
||||
.data = &mt8196_hfrpsys_hwv_data,
|
||||
|
|
@ -1241,6 +1360,8 @@ static int scpsys_probe(struct platform_device *pdev)
|
|||
struct device *parent;
|
||||
struct scpsys *scpsys;
|
||||
int num_domains, ret;
|
||||
u8 num_added_pds = 0;
|
||||
u8 *added_pds_idx;
|
||||
|
||||
soc = of_device_get_match_data(&pdev->dev);
|
||||
if (!soc) {
|
||||
|
|
@ -1254,6 +1375,19 @@ static int scpsys_probe(struct platform_device *pdev)
|
|||
if (!scpsys)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Temporarily store the IDs of the power domains that are added as in
|
||||
* case of a probe deferral this can be used to correctly cleanup all
|
||||
* of what was added before.
|
||||
*
|
||||
* Note that this array is used only in the probe function and must be
|
||||
* freed at the end, regardless of whether all of the power domains were
|
||||
* probed successfully or any failure happened.
|
||||
*/
|
||||
added_pds_idx = devm_kmalloc_array(dev, num_domains, sizeof(*added_pds_idx), GFP_KERNEL);
|
||||
if (!added_pds_idx)
|
||||
return -ENOMEM;
|
||||
|
||||
scpsys->dev = dev;
|
||||
scpsys->soc_data = soc;
|
||||
|
||||
|
|
@ -1284,13 +1418,15 @@ static int scpsys_probe(struct platform_device *pdev)
|
|||
for_each_available_child_of_node_scoped(np, node) {
|
||||
struct generic_pm_domain *domain;
|
||||
|
||||
domain = scpsys_add_one_domain(scpsys, node);
|
||||
domain = scpsys_add_one_domain(scpsys, node,
|
||||
added_pds_idx, &num_added_pds);
|
||||
if (IS_ERR(domain)) {
|
||||
ret = PTR_ERR(domain);
|
||||
goto err_cleanup_domains;
|
||||
}
|
||||
|
||||
ret = scpsys_add_subdomain(scpsys, node);
|
||||
ret = scpsys_add_subdomain(scpsys, node,
|
||||
added_pds_idx, &num_added_pds);
|
||||
if (ret)
|
||||
goto err_cleanup_domains;
|
||||
}
|
||||
|
|
@ -1306,10 +1442,11 @@ static int scpsys_probe(struct platform_device *pdev)
|
|||
goto err_cleanup_domains;
|
||||
}
|
||||
|
||||
devm_kfree(dev, added_pds_idx);
|
||||
return 0;
|
||||
|
||||
err_cleanup_domains:
|
||||
scpsys_domain_cleanup(scpsys);
|
||||
scpsys_domain_cleanup(scpsys, added_pds_idx, num_added_pds);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#define MTK_SCPD_MODEM_PWRSEQ BIT(10)
|
||||
#define MTK_SCPD_SKIP_RESET_B BIT(11)
|
||||
#define MTK_SCPD_INFRA_PWR_CTL BIT(12)
|
||||
#define MTK_SCPD_SIMPLE_PWRSEQ BIT(13)
|
||||
#define MTK_SCPD_MODEM_SECURE_PWRSEQ BIT(14)
|
||||
#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data ? \
|
||||
(_scpd)->data->caps & (_x) : \
|
||||
(_scpd)->hwv_data->caps & (_x))
|
||||
|
|
@ -64,6 +66,11 @@ enum scpsys_bus_prot_block {
|
|||
BUS_PROT_BLOCK_INFRA_NAO,
|
||||
BUS_PROT_BLOCK_SMI,
|
||||
BUS_PROT_BLOCK_SPM,
|
||||
BUS_PROT_BLOCK_IMG_SUB0,
|
||||
BUS_PROT_BLOCK_CAM_SUB1,
|
||||
BUS_PROT_BLOCK_CAM_SUB0,
|
||||
BUS_PROT_BLOCK_IPE_SUB0,
|
||||
BUS_PROT_BLOCK_VLP,
|
||||
BUS_PROT_BLOCK_COUNT,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
* @addr: Resource address as looped up using resource name from
|
||||
* cmd-db
|
||||
* @state_synced: Indicator that sync_state has been invoked for the rpmhpd resource
|
||||
* @skip_retention_level: Indicate that retention level should not be used for the power domain
|
||||
*/
|
||||
struct rpmhpd {
|
||||
struct device *dev;
|
||||
|
|
@ -58,7 +57,6 @@ struct rpmhpd {
|
|||
const char *res_name;
|
||||
u32 addr;
|
||||
bool state_synced;
|
||||
bool skip_retention_level;
|
||||
};
|
||||
|
||||
struct rpmhpd_desc {
|
||||
|
|
@ -191,7 +189,6 @@ static struct rpmhpd mxc = {
|
|||
.pd = { .name = "mxc", },
|
||||
.peer = &mxc_ao,
|
||||
.res_name = "mxc.lvl",
|
||||
.skip_retention_level = true,
|
||||
};
|
||||
|
||||
static struct rpmhpd mxc_ao = {
|
||||
|
|
@ -199,7 +196,6 @@ static struct rpmhpd mxc_ao = {
|
|||
.active_only = true,
|
||||
.peer = &mxc,
|
||||
.res_name = "mxc.lvl",
|
||||
.skip_retention_level = true,
|
||||
};
|
||||
|
||||
static struct rpmhpd nsp = {
|
||||
|
|
@ -309,10 +305,10 @@ static struct rpmhpd *sa8775p_rpmhpds[] = {
|
|||
[SA8775P_LMX] = &lmx,
|
||||
[SA8775P_MMCX] = &mmcx,
|
||||
[SA8775P_MMCX_AO] = &mmcx_ao,
|
||||
[SA8775P_MXC] = &mxc,
|
||||
[SA8775P_MXC_AO] = &mxc_ao,
|
||||
[SA8775P_MX] = &mx,
|
||||
[SA8775P_MX_AO] = &mx_ao,
|
||||
[SA8775P_MXC] = &mxc,
|
||||
[SA8775P_MXC_AO] = &mxc_ao,
|
||||
[SA8775P_NSP0] = &nsp0,
|
||||
[SA8775P_NSP1] = &nsp1,
|
||||
};
|
||||
|
|
@ -329,10 +325,10 @@ static struct rpmhpd *nord_rpmhpds[] = {
|
|||
[RPMHPD_EBI] = &ebi,
|
||||
[RPMHPD_GFX] = &gfx,
|
||||
[RPMHPD_GFX1] = &gfx1,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MMCX] = &mmcx,
|
||||
[RPMHPD_MMCX_AO] = &mmcx_ao,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_MXC_AO] = &mxc_ao,
|
||||
[RPMHPD_NSP0] = &nsp0,
|
||||
|
|
@ -484,9 +480,9 @@ static struct rpmhpd *sm7150_rpmhpds[] = {
|
|||
[RPMHPD_GFX] = &gfx,
|
||||
[RPMHPD_LCX] = &lcx,
|
||||
[RPMHPD_LMX] = &lmx,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
};
|
||||
|
||||
static const struct rpmhpd_desc sm7150_desc = {
|
||||
|
|
@ -702,11 +698,11 @@ static struct rpmhpd *hawi_rpmhpds[] = {
|
|||
[RPMHPD_LMX] = &lmx,
|
||||
[RPMHPD_MMCX] = &mmcx,
|
||||
[RPMHPD_MMCX_AO] = &mmcx_ao,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_MXC_AO] = &mxc_ao,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
[RPMHPD_NSP] = &nsp,
|
||||
[RPMHPD_NSP2] = &nsp2,
|
||||
};
|
||||
|
|
@ -813,18 +809,18 @@ static struct rpmhpd *glymur_rpmhpds[] = {
|
|||
[RPMHPD_CX_AO] = &cx_ao,
|
||||
[RPMHPD_EBI] = &ebi,
|
||||
[RPMHPD_GFX] = &gfx,
|
||||
[RPMHPD_GMXC] = &gmxc,
|
||||
[RPMHPD_LCX] = &lcx,
|
||||
[RPMHPD_LMX] = &lmx,
|
||||
[RPMHPD_MMCX] = &mmcx,
|
||||
[RPMHPD_MMCX_AO] = &mmcx_ao,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_MXC_AO] = &mxc_ao,
|
||||
[RPMHPD_MSS] = &mss,
|
||||
[RPMHPD_NSP] = &nsp,
|
||||
[RPMHPD_NSP2] = &nsp2,
|
||||
[RPMHPD_GMXC] = &gmxc,
|
||||
};
|
||||
|
||||
static const struct rpmhpd_desc glymur_desc = {
|
||||
|
|
@ -838,15 +834,15 @@ static struct rpmhpd *x1e80100_rpmhpds[] = {
|
|||
[RPMHPD_CX_AO] = &cx_ao,
|
||||
[RPMHPD_EBI] = &ebi,
|
||||
[RPMHPD_GFX] = &gfx,
|
||||
[RPMHPD_GMXC] = &gmxc,
|
||||
[RPMHPD_LCX] = &lcx,
|
||||
[RPMHPD_LMX] = &lmx,
|
||||
[RPMHPD_MMCX] = &mmcx,
|
||||
[RPMHPD_MMCX_AO] = &mmcx_ao,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_NSP] = &nsp,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_GMXC] = &gmxc,
|
||||
[RPMHPD_NSP] = &nsp,
|
||||
};
|
||||
|
||||
static const struct rpmhpd_desc x1e80100_desc = {
|
||||
|
|
@ -864,10 +860,10 @@ static struct rpmhpd *qcs8300_rpmhpds[] = {
|
|||
[RPMHPD_LMX] = &lmx,
|
||||
[RPMHPD_MMCX] = &mmcx_w_cx_parent,
|
||||
[RPMHPD_MMCX_AO] = &mmcx_ao_w_cx_parent,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_MXC_AO] = &mxc_ao,
|
||||
[RPMHPD_MX] = &mx,
|
||||
[RPMHPD_MX_AO] = &mx_ao,
|
||||
[RPMHPD_MXC] = &mxc,
|
||||
[RPMHPD_MXC_AO] = &mxc_ao,
|
||||
[RPMHPD_NSP0] = &nsp0,
|
||||
[RPMHPD_NSP1] = &nsp1,
|
||||
};
|
||||
|
|
@ -1097,7 +1093,15 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
|
|||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < rpmhpd->level_count; i++) {
|
||||
if (rpmhpd->skip_retention_level && buf[i] == RPMH_REGULATOR_LEVEL_RETENTION)
|
||||
/*
|
||||
* Most HW won't function properly at Retention. The minimum
|
||||
* operational level is the first level above Retention. The
|
||||
* small subset of HW that can operate at Retention isn't
|
||||
* controlled by HLOS. Skip the Retention level to avoid HW
|
||||
* failures when the PD is enabled without first having an
|
||||
* explicit OPP level set.
|
||||
*/
|
||||
if (buf[i] == RPMH_REGULATOR_LEVEL_RETENTION)
|
||||
continue;
|
||||
|
||||
rpmhpd->level[i] = buf[i];
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ config SYSC_RMOBILE
|
|||
bool "System Controller support for R-Mobile" if COMPILE_TEST
|
||||
|
||||
# SoC
|
||||
config MDLC_R8A78000
|
||||
bool "Module Controller support for R8A78000 (R-Car X5H)" if COMPILE_TEST
|
||||
select RESET_CONTROLLER
|
||||
|
||||
config SYSC_R8A7742
|
||||
bool "System Controller support for R8A7742 (RZ/G1H)" if COMPILE_TEST
|
||||
select SYSC_RCAR
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# SoC
|
||||
obj-$(CONFIG_MDLC_R8A78000) += r8a78000-mdlc.o
|
||||
obj-$(CONFIG_SYSC_R8A7742) += r8a7742-sysc.o
|
||||
obj-$(CONFIG_SYSC_R8A7743) += r8a7743-sysc.o
|
||||
obj-$(CONFIG_SYSC_R8A7745) += r8a7745-sysc.o
|
||||
|
|
|
|||
325
drivers/pmdomain/renesas/r8a78000-mdlc.c
Normal file
325
drivers/pmdomain/renesas/r8a78000-mdlc.c
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* R-Car X5H Module Controller
|
||||
*
|
||||
* Copyright (C) 2026 Glider bv
|
||||
*/
|
||||
|
||||
#include <linux/dev_printk.h>
|
||||
#include <linux/device-id/of.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/power/renesas,r8a78000-mdlc.h>
|
||||
|
||||
struct mod_map {
|
||||
int hw_id; /* Hardware module ID or -1 sentinel */
|
||||
};
|
||||
|
||||
struct mdlc_info {
|
||||
u32 base;
|
||||
const struct mod_map *mod_map;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct r8a78000_mdlc_priv - Module Controller Private Data
|
||||
*
|
||||
* @link: Link into list of MDLC instances
|
||||
* @genpd_data: PM domain provider data
|
||||
* @rcdev: Reset controller entity
|
||||
* @dev: MDLC device
|
||||
* @np: Device node in DT representing the MDLC
|
||||
* @mod_map: Mapping from hardware module IDs
|
||||
*/
|
||||
struct r8a78000_mdlc_priv {
|
||||
struct hlist_node link;
|
||||
struct genpd_onecell_data genpd_data;
|
||||
struct reset_controller_dev rcdev;
|
||||
struct device *dev;
|
||||
struct device_node *np;
|
||||
const struct mod_map *mod_map;
|
||||
};
|
||||
|
||||
static struct generic_pm_domain *r8a78000_genpd_always_on;
|
||||
static HLIST_HEAD(r8a78000_mdlc_list);
|
||||
static DEFINE_MUTEX(r8a78000_mdlc_lock); /* protects the two above */
|
||||
|
||||
static struct generic_pm_domain *r8a78000_genpd_xlate(
|
||||
const struct of_phandle_args *spec, void *data)
|
||||
{
|
||||
struct r8a78000_mdlc_priv *priv = container_of(data,
|
||||
struct r8a78000_mdlc_priv, genpd_data);
|
||||
struct device *dev = priv->dev;
|
||||
u32 id;
|
||||
|
||||
if (spec->args_count != 2)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
id = spec->args[0];
|
||||
|
||||
if (id >= R8A78000_MDLC_PD_AON) {
|
||||
dev_dbg(dev,
|
||||
"Mapping HW power domain 0x%x to always-on domain\n",
|
||||
id);
|
||||
return r8a78000_genpd_always_on;
|
||||
}
|
||||
|
||||
/* For now only always-on domains are supported */
|
||||
dev_err(dev, "Unknown power domain 0x%x\n", id);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
#define rcdev_to_priv(_rcdev) \
|
||||
container_of(_rcdev, struct r8a78000_mdlc_priv, rcdev)
|
||||
|
||||
static const struct mod_map *mod_map_find(const struct mod_map *map, u32 id)
|
||||
{
|
||||
if (!map)
|
||||
return NULL;
|
||||
|
||||
for (; map->hw_id >= 0; map++) {
|
||||
if (map->hw_id == id)
|
||||
return map;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int r8a78000_mdlc_reset_xlate(struct reset_controller_dev *rcdev,
|
||||
const struct of_phandle_args *spec)
|
||||
{
|
||||
struct r8a78000_mdlc_priv *priv = rcdev_to_priv(rcdev);
|
||||
struct device *dev = priv->dev;
|
||||
const struct mod_map *map;
|
||||
u32 id;
|
||||
|
||||
if (spec->args_count != 1)
|
||||
return -EINVAL;
|
||||
|
||||
id = spec->args[0];
|
||||
|
||||
map = mod_map_find(priv->mod_map, id);
|
||||
if (!map) {
|
||||
dev_err(dev, "Unknown reset 0x%x\n", id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Ignoring HW reset 0x%x\n", id);
|
||||
return id;
|
||||
}
|
||||
|
||||
#define DEFINE_MDLC_RESET_WRAPPER(op) \
|
||||
static int r8a78000_mdlc_ ## op(struct reset_controller_dev *rcdev, \
|
||||
unsigned long id) \
|
||||
{ \
|
||||
struct r8a78000_mdlc_priv *priv = rcdev_to_priv(rcdev); \
|
||||
\
|
||||
dev_dbg(priv->dev, "%s: Ignoring\n", __func__); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
DEFINE_MDLC_RESET_WRAPPER(reset)
|
||||
DEFINE_MDLC_RESET_WRAPPER(assert)
|
||||
DEFINE_MDLC_RESET_WRAPPER(deassert)
|
||||
DEFINE_MDLC_RESET_WRAPPER(status)
|
||||
|
||||
static const struct reset_control_ops r8a78000_mdlc_reset_ops = {
|
||||
.reset = r8a78000_mdlc_reset,
|
||||
.assert = r8a78000_mdlc_assert,
|
||||
.deassert = r8a78000_mdlc_deassert,
|
||||
.status = r8a78000_mdlc_status,
|
||||
};
|
||||
|
||||
static int r8a78000_mdlc_attach_dev(struct generic_pm_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct r8a78000_mdlc_priv *priv;
|
||||
struct of_phandle_args pd_spec;
|
||||
const struct mod_map *map;
|
||||
unsigned int id;
|
||||
int ret;
|
||||
|
||||
ret = of_parse_phandle_with_args(np, "power-domains",
|
||||
"#power-domain-cells", 0, &pd_spec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
scoped_guard(mutex, &r8a78000_mdlc_lock) {
|
||||
hlist_for_each_entry(priv, &r8a78000_mdlc_list, link) {
|
||||
if (priv->np == pd_spec.np)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv) {
|
||||
dev_err(dev, "%s: MDLC %pOF not found\n", __func__, pd_spec.np);
|
||||
of_node_put(pd_spec.np);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
id = pd_spec.args[1];
|
||||
of_node_put(pd_spec.np);
|
||||
|
||||
map = mod_map_find(priv->mod_map, id);
|
||||
if (!map) {
|
||||
dev_err(dev, "Unknown module 0x%x\n", id);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Ignoring HW module 0x%x\n", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r8a78000_mdlc_unlink(void *data)
|
||||
{
|
||||
struct r8a78000_mdlc_priv *priv = data;
|
||||
|
||||
scoped_guard(mutex, &r8a78000_mdlc_lock) {
|
||||
hlist_del(&priv->link);
|
||||
}
|
||||
}
|
||||
|
||||
static void r8a78000_genpd_del_provider(void *data)
|
||||
{
|
||||
of_genpd_del_provider(data);
|
||||
}
|
||||
|
||||
static int r8a78000_genpd_always_on_singleton(struct device *dev)
|
||||
{
|
||||
struct generic_pm_domain *genpd;
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&r8a78000_mdlc_lock);
|
||||
|
||||
if (r8a78000_genpd_always_on)
|
||||
return 0;
|
||||
|
||||
genpd = kzalloc_obj(*genpd);
|
||||
if (!genpd)
|
||||
return -ENOMEM;
|
||||
|
||||
genpd->name = "always-on";
|
||||
genpd->attach_dev = r8a78000_mdlc_attach_dev;
|
||||
|
||||
ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
|
||||
if (ret) {
|
||||
kfree(genpd);
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to create always-on domain\n");
|
||||
}
|
||||
|
||||
r8a78000_genpd_always_on = genpd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int r8a78000_mdlc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct r8a78000_mdlc_priv *priv;
|
||||
const struct mdlc_info *info;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
ret = r8a78000_genpd_always_on_singleton(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
info = of_device_get_match_data(dev);
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dev = dev;
|
||||
priv->np = np;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
for (; info->base; info++) {
|
||||
if (info->base == res->start)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!info->base) {
|
||||
dev_dbg(dev, "Unsupported MDLC instance 0x%pa\n", &res->start);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
priv->mod_map = info->mod_map;
|
||||
|
||||
scoped_guard(mutex, &r8a78000_mdlc_lock) {
|
||||
hlist_add_head(&priv->link, &r8a78000_mdlc_list);
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(dev, r8a78000_mdlc_unlink, priv);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add action\n");
|
||||
|
||||
/* Note that no actual domains are registered, just need translation */
|
||||
priv->genpd_data.xlate = r8a78000_genpd_xlate;
|
||||
ret = of_genpd_add_provider_onecell(np, &priv->genpd_data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to register genpd provider\n");
|
||||
|
||||
ret = devm_add_action_or_reset(dev, r8a78000_genpd_del_provider, np);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to add unregister action\n");
|
||||
|
||||
priv->rcdev.ops = &r8a78000_mdlc_reset_ops;
|
||||
priv->rcdev.of_node = np;
|
||||
priv->rcdev.of_reset_n_cells = 1;
|
||||
priv->rcdev.of_xlate = r8a78000_mdlc_reset_xlate;
|
||||
|
||||
ret = devm_reset_controller_register(dev, &priv->rcdev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to register reset controller\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mod_map r8a78000_mdlc_perw_mod_default[] = {
|
||||
{ 0x54 }, /* HSCIF0 */
|
||||
{ -1 }
|
||||
};
|
||||
|
||||
static const struct mdlc_info r8a78000_mdlc_default[] = {
|
||||
{
|
||||
.base = 0xc05d0000 /* mdlc_perw */,
|
||||
.mod_map = r8a78000_mdlc_perw_mod_default,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct of_device_id r8a78000_mdlc_match[] = {
|
||||
{
|
||||
.compatible = "renesas,r8a78000-mdlc",
|
||||
.data = &r8a78000_mdlc_default,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver r8a78000_mdlc_driver = {
|
||||
.probe = r8a78000_mdlc_probe,
|
||||
.driver = {
|
||||
.name = "r8a78000-mdlc",
|
||||
.of_match_table = r8a78000_mdlc_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
||||
builtin_platform_driver(r8a78000_mdlc_driver)
|
||||
|
||||
MODULE_DESCRIPTION("R-Car X5H MDLC Driver");
|
||||
|
|
@ -204,6 +204,20 @@ struct rockchip_pmu {
|
|||
.active_wakeup = wakeup, \
|
||||
}
|
||||
|
||||
#define DOMAIN_M_R(_name, pwr, status, req, idle, ack, wakeup, regulator) \
|
||||
{ \
|
||||
.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), \
|
||||
.active_wakeup = wakeup, \
|
||||
.need_regulator = regulator, \
|
||||
}
|
||||
|
||||
#define DOMAIN_RK3036(_name, req, ack, idle, wakeup) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
|
|
@ -241,8 +255,8 @@ struct rockchip_pmu {
|
|||
#define DOMAIN_RK3562(name, pwr, req, g_mask, mem, wakeup) \
|
||||
DOMAIN_M_G_SD(name, pwr, pwr, req, req, req, g_mask, mem, wakeup, false)
|
||||
|
||||
#define DOMAIN_RK3568(name, pwr, req, wakeup) \
|
||||
DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)
|
||||
#define DOMAIN_RK3568(name, pwr, req, wakeup, regulator) \
|
||||
DOMAIN_M_R(name, pwr, pwr, req, req, req, wakeup, regulator)
|
||||
|
||||
#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)
|
||||
|
|
@ -1274,15 +1288,15 @@ static const struct rockchip_domain_info rk3562_pm_domains[] = {
|
|||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3568_pm_domains[] = {
|
||||
[RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false),
|
||||
[RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false),
|
||||
[RK3568_PD_VI] = DOMAIN_RK3568("vi", BIT(6), BIT(3), false),
|
||||
[RK3568_PD_VO] = DOMAIN_RK3568("vo", BIT(7), BIT(4), false),
|
||||
[RK3568_PD_RGA] = DOMAIN_RK3568("rga", BIT(5), BIT(5), false),
|
||||
[RK3568_PD_VPU] = DOMAIN_RK3568("vpu", BIT(2), BIT(6), false),
|
||||
[RK3568_PD_RKVDEC] = DOMAIN_RK3568("vdec", BIT(4), BIT(8), false),
|
||||
[RK3568_PD_RKVENC] = DOMAIN_RK3568("venc", BIT(3), BIT(7), false),
|
||||
[RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false),
|
||||
[RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false, true),
|
||||
[RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false, false),
|
||||
[RK3568_PD_VI] = DOMAIN_RK3568("vi", BIT(6), BIT(3), false, false),
|
||||
[RK3568_PD_VO] = DOMAIN_RK3568("vo", BIT(7), BIT(4), false, false),
|
||||
[RK3568_PD_RGA] = DOMAIN_RK3568("rga", BIT(5), BIT(5), false, false),
|
||||
[RK3568_PD_VPU] = DOMAIN_RK3568("vpu", BIT(2), BIT(6), false, false),
|
||||
[RK3568_PD_RKVDEC] = DOMAIN_RK3568("vdec", BIT(4), BIT(8), false, false),
|
||||
[RK3568_PD_RKVENC] = DOMAIN_RK3568("venc", BIT(3), BIT(7), false, false),
|
||||
[RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false, false),
|
||||
};
|
||||
|
||||
static const struct rockchip_domain_info rk3576_pm_domains[] = {
|
||||
|
|
|
|||
|
|
@ -137,6 +137,13 @@ static char *tegra_bpmp_powergate_get_name(struct tegra_bpmp *bpmp,
|
|||
if (err < 0 || msg.rx.ret < 0)
|
||||
return NULL;
|
||||
|
||||
if (response.get_name.name[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
if (dev_to_node(bpmp->dev) != NUMA_NO_NODE)
|
||||
return kasprintf(GFP_KERNEL, "%d-%s", dev_to_node(bpmp->dev),
|
||||
response.get_name.name);
|
||||
|
||||
return kstrdup(response.get_name.name, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +241,7 @@ tegra_bpmp_probe_powergates(struct tegra_bpmp *bpmp,
|
|||
struct tegra_powergate_info *info = &powergates[count];
|
||||
|
||||
info->name = tegra_bpmp_powergate_get_name(bpmp, id);
|
||||
if (!info->name || info->name[0] == '\0') {
|
||||
if (!info->name) {
|
||||
num_holes++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,6 +357,7 @@ config ARCH_R8A78000
|
|||
bool "ARM64 Platform support for R8A78000 (R-Car X5H)"
|
||||
default y if ARCH_RENESAS
|
||||
select ARCH_RCAR_GEN5
|
||||
select MDLC_R8A78000
|
||||
help
|
||||
This enables support for the Renesas R-Car X5H SoC.
|
||||
|
||||
|
|
|
|||
61
include/dt-bindings/power/amlogic,a9-pwrc.h
Normal file
61
include/dt-bindings/power/amlogic,a9-pwrc.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
|
||||
/*
|
||||
* Copyright (C) 2026 Amlogic, Inc. All rights reserved
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_AMLOGIC_A9_POWER_H
|
||||
#define _DT_BINDINGS_AMLOGIC_A9_POWER_H
|
||||
|
||||
#define PWRC_A9_DSPA_ID 0
|
||||
#define PWRC_A9_U3HSG_U3_ID 1
|
||||
#define PWRC_A9_DP_ID 2
|
||||
#define PWRC_A9_DOS_HCODEC_ID 3
|
||||
#define PWRC_A9_TAHOE_ID 4
|
||||
#define PWRC_A9_DOS_HEVC_ID 5
|
||||
#define PWRC_A9_U2H_ID 6
|
||||
#define PWRC_A9_U3DRD_B_ID 7
|
||||
#define PWRC_A9_VPU_HDMI_ID 8
|
||||
#define PWRC_A9_U2DRD_ID 9
|
||||
#define PWRC_A9_U3DRD_A_ID 10
|
||||
#define PWRC_A9_SD_EMMC_C_ID 11
|
||||
#define PWRC_A9_GE2D_ID 12
|
||||
#define PWRC_A9_AMFC_ID 13
|
||||
#define PWRC_A9_EDPTX_ID 14
|
||||
#define PWRC_A9_OPP_ID 15
|
||||
#define PWRC_A9_VICP_ID 16
|
||||
#define PWRC_A9_SD_EMMC_A_ID 17
|
||||
#define PWRC_A9_SD_EMMC_B_ID 18
|
||||
#define PWRC_A9_ETH_ID 19
|
||||
#define PWRC_A9_PCIE_A_ID 20
|
||||
#define PWRC_A9_PCIE_B_ID 21
|
||||
#define PWRC_A9_NNA_4T_ID 22
|
||||
#define PWRC_A9_HDMIRX_ID 23
|
||||
#define PWRC_A9_CVE_ID 24
|
||||
#define PWRC_A9_ISP_ID 25
|
||||
#define PWRC_A9_ETH_1G_ID 26
|
||||
#define PWRC_A9_U3HSG_HSG_ID 27
|
||||
#define PWRC_A9_U3DPPHY_U3_ID 28
|
||||
#define PWRC_A9_U3DPPHY_DP_ID 29
|
||||
#define PWRC_A9_PCIE3PHY_ID 30
|
||||
#define PWRC_A9_U3HSG_PCIE2_ID 31
|
||||
#define PWRC_A9_MALI_TOP_ID 32
|
||||
#define PWRC_A9_AO_SED_ID 33
|
||||
#define PWRC_A9_AO_IR_ID 34
|
||||
#define PWRC_A9_AO_UART_B_ID 35
|
||||
#define PWRC_A9_AO_UART_C_ID 36
|
||||
#define PWRC_A9_AO_UART_D_ID 37
|
||||
#define PWRC_A9_AO_SPISG_ID 38
|
||||
#define PWRC_A9_AO_UART_E_ID 39
|
||||
#define PWRC_A9_AO_CEC_ID 40
|
||||
#define PWRC_A9_EE_SRAMA_ID 41
|
||||
#define PWRC_A9_AUDIO_ID 42
|
||||
#define PWRC_A9_DMC0_ID 43
|
||||
#define PWRC_A9_GIC_ID 44
|
||||
#define PWRC_A9_DDRPHY_ID 45
|
||||
#define PWRC_A9_AUCPU_ID 46
|
||||
#define PWRC_A9_DSI0_ID 47
|
||||
#define PWRC_A9_DSI1_ID 48
|
||||
#define PWRC_A9_CAN0_ID 49
|
||||
#define PWRC_A9_CAN1_ID 50
|
||||
|
||||
#endif
|
||||
23
include/dt-bindings/power/mediatek,mt6858-power.h
Normal file
23
include/dt-bindings/power/mediatek,mt6858-power.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
|
||||
#ifndef _DT_BINDINGS_POWER_MT6858_POWER_H
|
||||
#define _DT_BINDINGS_POWER_MT6858_POWER_H
|
||||
|
||||
#define MT6858_POWER_DOMAIN_MD 0
|
||||
#define MT6858_POWER_DOMAIN_CONN 1
|
||||
#define MT6858_POWER_DOMAIN_AUDIO 2
|
||||
#define MT6858_POWER_DOMAIN_MM_INFRA 3
|
||||
#define MT6858_POWER_DOMAIN_ISP_IMG1 4
|
||||
#define MT6858_POWER_DOMAIN_ISP_IMG2 5
|
||||
#define MT6858_POWER_DOMAIN_ISP_IPE 6
|
||||
#define MT6858_POWER_DOMAIN_VDE0 7
|
||||
#define MT6858_POWER_DOMAIN_VEN0 8
|
||||
#define MT6858_POWER_DOMAIN_CAM_MAIN 9
|
||||
#define MT6858_POWER_DOMAIN_CAM_SUBA 10
|
||||
#define MT6858_POWER_DOMAIN_CAM_SUBB 11
|
||||
#define MT6858_POWER_DOMAIN_DIS0 12
|
||||
#define MT6858_POWER_DOMAIN_MM_PROC_DORMANT 13
|
||||
#define MT6858_POWER_DOMAIN_CSI_RX 14
|
||||
#define MT6858_POWER_DOMAIN_SSUSB 15
|
||||
|
||||
#endif /* _DT_BINDINGS_POWER_MT6858_POWER_H */
|
||||
|
|
@ -30,6 +30,10 @@
|
|||
#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT 0
|
||||
#define MT8196_POWER_DOMAIN_SSR 1
|
||||
|
||||
/* HFRPSYS Multimedia Power Control (MMPC) - Direct Control */
|
||||
#define MT8196_POWER_DOMAIN_EDPTX 0
|
||||
#define MT8196_POWER_DOMAIN_DPTX 1
|
||||
|
||||
/* HFRPSYS MultiMedia Power Control (MMPC) - HW Voter */
|
||||
#define MT8196_POWER_DOMAIN_VDE0 0
|
||||
#define MT8196_POWER_DOMAIN_VDE1 1
|
||||
|
|
|
|||
15
include/dt-bindings/power/renesas,r8a78000-mdlc.h
Normal file
15
include/dt-bindings/power/renesas,r8a78000-mdlc.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (C) 2026 Glider bv
|
||||
*/
|
||||
#ifndef __DT_BINDINGS_POWER_RENESAS_R8A78000_MDLC_H__
|
||||
#define __DT_BINDINGS_POWER_RENESAS_R8A78000_MDLC_H__
|
||||
|
||||
/* R-Car X5H Module Controller Always-On Power Domains */
|
||||
|
||||
#define R8A78000_MDLC_PD_AON 0x40
|
||||
#define R8A78000_MDLC_PD_SCP 0x41
|
||||
#define R8A78000_MDLC_PD_APL 0x42
|
||||
#define R8A78000_MDLC_PD_ACL 0x43
|
||||
|
||||
#endif /* __DT_BINDINGS_POWER_RENESAS_R8A78000_MDLC_H__ */
|
||||
|
|
@ -22,6 +22,9 @@
|
|||
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \
|
||||
ARM_SMCCC_OWNER_SIP, fn_id)
|
||||
|
||||
/* Modem related SMC call */
|
||||
#define MTK_SIP_KERNEL_CCCI_CONTROL MTK_SIP_SMC_CMD(0x505)
|
||||
|
||||
/* DVFSRC SMC calls */
|
||||
#define MTK_SIP_DVFSRC_VCOREFS_CONTROL MTK_SIP_SMC_CMD(0x506)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user