power-domains:
- add support for new power domain driver. - add support for mt8183 and mt8192 devapc: - add support for the devapc device found on mt6779 to identify of malicious bus accesses from a controller to a device mmsys: - move DDP routing IDs into the driver cmdq: - drop timeout handler support as not usefull scpsys: - print warning on theoretical error -----BEGIN PGP SIGNATURE----- iQJLBAABCAA1FiEEUdvKHhzqrUYPB/u8L21+TfbCqH4FAl/EDZoXHG1hdHRoaWFz LmJnZ0BnbWFpbC5jb20ACgkQL21+TfbCqH7zEw/8DW7/eqjvP71tJG7qvlhASy1R S6YYrnmx8R/A41um3tAYcfgPCm+xPGeqIsBRFWOxmLmw71ebu/EQyuuvGFx6qY2c p4pZdafkM7IrNYD0JLpLIpFZAqikPtz2WefzPqHD8WTaGKqQ+neoNWS2twVIpiTz N0wpkl3BuFTcjirDaeME8BY31UxhP2E9LK+IMSZmfnhfIJjgw4/A5/pbAVM+EUhC LqqSRn1uGmvibAQXVFDyhk/tLZJCe4X3OLkgXwlTKCIcd0qpVCWT+2xoxIV7r30G Ldddt8LwVVuebSaY5NTtQQy4t0ZBx79a+17eTDt/+cIc6k3F5Bucnl/dKssWS9dO /lXs5jpJvcmeWNgvYhbGhXj42CrekY3I3aZpZnJDCl6dG74NWbWSe+xAxxH417s0 9t5cNDLW9L21NhkMGXFX+a8LbMiT1s+UeM4UXHnCGHX2Mx2cQoP/ATr7d5ED+Jr6 3xdKO6r7YnJANZ4UAvIVhbbak2pMT5BUhU/jM1LAMZ/JkEscfjyvdOyorAMFR5Ka hUFcfaJJ0hcVkfSEbF0LPsoNI8XHIY1i0bar4ZIKYr6asTgtVyHHh/BHfO25LW+4 T4Vpr3ugj7znuomFuPCYXfy/3NN1TlFWfTtI8GwGCAdX6gihdoJ/We8KRqoCWrdp bEefKIDJxFWMNMA48j0= =mQNT -----END PGP SIGNATURE----- Merge tag 'v5.10-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into arm/drivers power-domains: - add support for new power domain driver. - add support for mt8183 and mt8192 devapc: - add support for the devapc device found on mt6779 to identify of malicious bus accesses from a controller to a device mmsys: - move DDP routing IDs into the driver cmdq: - drop timeout handler support as not usefull scpsys: - print warning on theoretical error * tag 'v5.10-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux: (21 commits) soc: mediatek: mmsys: Use devm_platform_ioremap_resource() soc / drm: mediatek: Move DDP component defines into mtk-mmsys.h soc: mediatek: add mt6779 devapc driver dt-bindings: devapc: add bindings for mtk-devapc soc / drm: mediatek: cmdq: Remove timeout handler in helper function soc: mediatek: pm-domains: Add support for mt8192 soc: mediatek: pm-domains: Add default power off flag soc: mediatek: pm-domains: Add support for mt8183 soc: mediatek: pm-domains: Allow bus protection to ignore clear ack soc: mediatek: pm-domains: Add subsystem clocks soc: mediatek: pm-domains: Add extra sram control soc: mediatek: pm-domains: Add SMI block as bus protection block soc: mediatek: pm_domains: Make bus protection generic soc: mediatek: pm-domains: Add bus protection protocol soc: mediatek: Add MediaTek SCPSYS power domains dt-bindings: power: Add MT8192 power domains dt-bindings: power: Add MT8183 power domains dt-bindings: power: Add bindings for the Mediatek SCPSYS power domains controller mfd: syscon: Add syscon_regmap_lookup_by_phandle_optional() function. MAINTAINERS: change mediatek wiki page ... Link: https://lore.kernel.org/r/b03fe343-e183-c6f3-f2dc-4c58aae3146b@gmail.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Коммит
bbecede458
|
@ -0,0 +1,293 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/power/mediatek,power-controller.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek Power Domains Controller
|
||||
|
||||
maintainers:
|
||||
- Weiyi Lu <weiyi.lu@mediatek.com>
|
||||
- Matthias Brugger <mbrugger@suse.com>
|
||||
|
||||
description: |
|
||||
Mediatek processors include support for multiple power domains which can be
|
||||
powered up/down by software based on different application scenes to save power.
|
||||
|
||||
IP cores belonging to a power domain should contain a 'power-domains'
|
||||
property that is a phandle for SCPSYS node representing the domain.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
const: power-controller
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt8173-power-controller
|
||||
- mediatek,mt8183-power-controller
|
||||
- mediatek,mt8192-power-controller
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^power-domain@[0-9a-f]+$":
|
||||
type: object
|
||||
description: |
|
||||
Represents the power domains within the power controller node as documented
|
||||
in Documentation/devicetree/bindings/power/power-domain.yaml.
|
||||
|
||||
properties:
|
||||
|
||||
'#power-domain-cells':
|
||||
description:
|
||||
Must be 0 for nodes representing a single PM domain and 1 for nodes
|
||||
providing multiple PM domains.
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
description: |
|
||||
Power domain index. Valid values are defined in:
|
||||
"include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
|
||||
"include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
|
||||
"include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: |
|
||||
A number of phandles to clocks that need to be enabled during domain
|
||||
power-up sequencing.
|
||||
|
||||
clock-names:
|
||||
description: |
|
||||
List of names of clocks, in order to match the power-up sequencing
|
||||
for each power domain we need to group the clocks by name. BASIC
|
||||
clocks need to be enabled before enabling the corresponding power
|
||||
domain, and should not have a '-' in their name (i.e mm, mfg, venc).
|
||||
SUSBYS clocks need to be enabled before releasing the bus protection,
|
||||
and should contain a '-' in their name (i.e mm-0, isp-0, cam-0).
|
||||
|
||||
In order to follow properly the power-up sequencing, the clocks must
|
||||
be specified by order, adding first the BASIC clocks followed by the
|
||||
SUSBSYS clocks.
|
||||
|
||||
mediatek,infracfg:
|
||||
$ref: /schemas/types.yaml#definitions/phandle
|
||||
description: phandle to the device containing the INFRACFG register range.
|
||||
|
||||
mediatek,smi:
|
||||
$ref: /schemas/types.yaml#definitions/phandle
|
||||
description: phandle to the device containing the SMI register range.
|
||||
|
||||
patternProperties:
|
||||
"^power-domain@[0-9a-f]+$":
|
||||
type: object
|
||||
description: |
|
||||
Represents a power domain child within a power domain parent node.
|
||||
|
||||
properties:
|
||||
|
||||
'#power-domain-cells':
|
||||
description:
|
||||
Must be 0 for nodes representing a single PM domain and 1 for nodes
|
||||
providing multiple PM domains.
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: |
|
||||
A number of phandles to clocks that need to be enabled during domain
|
||||
power-up sequencing.
|
||||
|
||||
clock-names:
|
||||
description: |
|
||||
List of names of clocks, in order to match the power-up sequencing
|
||||
for each power domain we need to group the clocks by name. BASIC
|
||||
clocks need to be enabled before enabling the corresponding power
|
||||
domain, and should not have a '-' in their name (i.e mm, mfg, venc).
|
||||
SUSBYS clocks need to be enabled before releasing the bus protection,
|
||||
and should contain a '-' in their name (i.e mm-0, isp-0, cam-0).
|
||||
|
||||
In order to follow properly the power-up sequencing, the clocks must
|
||||
be specified by order, adding first the BASIC clocks followed by the
|
||||
SUSBSYS clocks.
|
||||
|
||||
mediatek,infracfg:
|
||||
$ref: /schemas/types.yaml#definitions/phandle
|
||||
description: phandle to the device containing the INFRACFG register range.
|
||||
|
||||
mediatek,smi:
|
||||
$ref: /schemas/types.yaml#definitions/phandle
|
||||
description: phandle to the device containing the SMI register range.
|
||||
|
||||
patternProperties:
|
||||
"^power-domain@[0-9a-f]+$":
|
||||
type: object
|
||||
description: |
|
||||
Represents a power domain child within a power domain parent node.
|
||||
|
||||
properties:
|
||||
|
||||
'#power-domain-cells':
|
||||
description:
|
||||
Must be 0 for nodes representing a single PM domain and 1 for nodes
|
||||
providing multiple PM domains.
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: |
|
||||
A number of phandles to clocks that need to be enabled during domain
|
||||
power-up sequencing.
|
||||
|
||||
clock-names:
|
||||
description: |
|
||||
List of names of clocks, in order to match the power-up sequencing
|
||||
for each power domain we need to group the clocks by name. BASIC
|
||||
clocks need to be enabled before enabling the corresponding power
|
||||
domain, and should not have a '-' in their name (i.e mm, mfg, venc).
|
||||
SUSBYS clocks need to be enabled before releasing the bus protection,
|
||||
and should contain a '-' in their name (i.e mm-0, isp-0, cam-0).
|
||||
|
||||
In order to follow properly the power-up sequencing, the clocks must
|
||||
be specified by order, adding first the BASIC clocks followed by the
|
||||
SUSBSYS clocks.
|
||||
|
||||
mediatek,infracfg:
|
||||
$ref: /schemas/types.yaml#definitions/phandle
|
||||
description: phandle to the device containing the INFRACFG register range.
|
||||
|
||||
mediatek,smi:
|
||||
$ref: /schemas/types.yaml#definitions/phandle
|
||||
description: phandle to the device containing the SMI register range.
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8173-clk.h>
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
scpsys: syscon@10006000 {
|
||||
compatible = "syscon", "simple-mfd";
|
||||
reg = <0 0x10006000 0 0x1000>;
|
||||
|
||||
spm: power-controller {
|
||||
compatible = "mediatek,mt8173-power-controller";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
/* power domains of the SoC */
|
||||
power-domain@MT8173_POWER_DOMAIN_VDEC {
|
||||
reg = <MT8173_POWER_DOMAIN_VDEC>;
|
||||
clocks = <&topckgen CLK_TOP_MM_SEL>;
|
||||
clock-names = "mm";
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_VENC {
|
||||
reg = <MT8173_POWER_DOMAIN_VENC>;
|
||||
clocks = <&topckgen CLK_TOP_MM_SEL>,
|
||||
<&topckgen CLK_TOP_VENC_SEL>;
|
||||
clock-names = "mm", "venc";
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_ISP {
|
||||
reg = <MT8173_POWER_DOMAIN_ISP>;
|
||||
clocks = <&topckgen CLK_TOP_MM_SEL>;
|
||||
clock-names = "mm";
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_MM {
|
||||
reg = <MT8173_POWER_DOMAIN_MM>;
|
||||
clocks = <&topckgen CLK_TOP_MM_SEL>;
|
||||
clock-names = "mm";
|
||||
#power-domain-cells = <0>;
|
||||
mediatek,infracfg = <&infracfg>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_VENC_LT {
|
||||
reg = <MT8173_POWER_DOMAIN_VENC_LT>;
|
||||
clocks = <&topckgen CLK_TOP_MM_SEL>,
|
||||
<&topckgen CLK_TOP_VENC_LT_SEL>;
|
||||
clock-names = "mm", "venclt";
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_AUDIO {
|
||||
reg = <MT8173_POWER_DOMAIN_AUDIO>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_USB {
|
||||
reg = <MT8173_POWER_DOMAIN_USB>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
power-domain@MT8173_POWER_DOMAIN_MFG_ASYNC {
|
||||
reg = <MT8173_POWER_DOMAIN_MFG_ASYNC>;
|
||||
clocks = <&clk26m>;
|
||||
clock-names = "mfg";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
power-domain@MT8173_POWER_DOMAIN_MFG_2D {
|
||||
reg = <MT8173_POWER_DOMAIN_MFG_2D>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
power-domain@MT8173_POWER_DOMAIN_MFG {
|
||||
reg = <MT8173_POWER_DOMAIN_MFG>;
|
||||
#power-domain-cells = <0>;
|
||||
mediatek,infracfg = <&infracfg>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,58 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# # Copyright 2020 MediaTek Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/soc/mediatek/devapc.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: MediaTek Device Access Permission Control driver
|
||||
|
||||
description: |
|
||||
MediaTek bus fabric provides TrustZone security support and data
|
||||
protection to prevent slaves from being accessed by unexpected masters.
|
||||
The security violation is logged and sent to the processor for further
|
||||
analysis and countermeasures.
|
||||
|
||||
maintainers:
|
||||
- Neal Liu <neal.liu@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt6779-devapc
|
||||
|
||||
reg:
|
||||
description: The base address of devapc register bank
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description: A single interrupt specifier
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: Contains module clock source and clock names
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
description: Names of the clocks list in clocks property
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/mt6779-clk.h>
|
||||
|
||||
devapc: devapc@10207000 {
|
||||
compatible = "mediatek,mt6779-devapc";
|
||||
reg = <0x10207000 0x1000>;
|
||||
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&infracfg_ao CLK_INFRA_DEVICE_APC>;
|
||||
clock-names = "devapc-infra-clock";
|
||||
};
|
|
@ -2067,7 +2067,7 @@ M: Matthias Brugger <matthias.bgg@gmail.com>
|
|||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
W: https://mtk.bcnfs.org/
|
||||
W: https://mtk.wiki.kernel.org/
|
||||
C: irc://chat.freenode.net/linux-mediatek
|
||||
F: arch/arm/boot/dts/mt6*
|
||||
F: arch/arm/boot/dts/mt7*
|
||||
|
|
|
@ -824,8 +824,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
|
|||
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
|
||||
mtk_crtc->cmdq_client =
|
||||
cmdq_mbox_create(mtk_crtc->mmsys_dev,
|
||||
drm_crtc_index(&mtk_crtc->base),
|
||||
2000);
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
if (IS_ERR(mtk_crtc->cmdq_client)) {
|
||||
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
|
||||
drm_crtc_index(&mtk_crtc->base));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define MTK_DRM_DDP_COMP_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/soc/mediatek/mtk-mmsys.h>
|
||||
|
||||
struct device;
|
||||
struct device_node;
|
||||
|
@ -35,39 +36,6 @@ enum mtk_ddp_comp_type {
|
|||
MTK_DDP_COMP_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum mtk_ddp_comp_id {
|
||||
DDP_COMPONENT_AAL0,
|
||||
DDP_COMPONENT_AAL1,
|
||||
DDP_COMPONENT_BLS,
|
||||
DDP_COMPONENT_CCORR,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_COLOR1,
|
||||
DDP_COMPONENT_DITHER,
|
||||
DDP_COMPONENT_DPI0,
|
||||
DDP_COMPONENT_DPI1,
|
||||
DDP_COMPONENT_DSI0,
|
||||
DDP_COMPONENT_DSI1,
|
||||
DDP_COMPONENT_DSI2,
|
||||
DDP_COMPONENT_DSI3,
|
||||
DDP_COMPONENT_GAMMA,
|
||||
DDP_COMPONENT_OD0,
|
||||
DDP_COMPONENT_OD1,
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_OVL_2L0,
|
||||
DDP_COMPONENT_OVL_2L1,
|
||||
DDP_COMPONENT_OVL1,
|
||||
DDP_COMPONENT_PWM0,
|
||||
DDP_COMPONENT_PWM1,
|
||||
DDP_COMPONENT_PWM2,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_RDMA1,
|
||||
DDP_COMPONENT_RDMA2,
|
||||
DDP_COMPONENT_UFOE,
|
||||
DDP_COMPONENT_WDMA0,
|
||||
DDP_COMPONENT_WDMA1,
|
||||
DDP_COMPONENT_ID_MAX,
|
||||
};
|
||||
|
||||
struct mtk_ddp_comp;
|
||||
struct cmdq_pkt;
|
||||
struct mtk_ddp_comp_funcs {
|
||||
|
|
|
@ -255,6 +255,24 @@ struct regmap *syscon_regmap_lookup_by_phandle_args(struct device_node *np,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_args);
|
||||
|
||||
/*
|
||||
* It behaves the same as syscon_regmap_lookup_by_phandle() except where
|
||||
* there is no regmap phandle. In this case, instead of returning -ENODEV,
|
||||
* the function returns NULL.
|
||||
*/
|
||||
struct regmap *syscon_regmap_lookup_by_phandle_optional(struct device_node *np,
|
||||
const char *property)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = syscon_regmap_lookup_by_phandle(np, property);
|
||||
if (IS_ERR(regmap) && PTR_ERR(regmap) == -ENODEV)
|
||||
return NULL;
|
||||
|
||||
return regmap;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_optional);
|
||||
|
||||
static int syscon_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
|
|
@ -17,6 +17,15 @@ config MTK_CMDQ
|
|||
time limitation, such as updating display configuration during the
|
||||
vblank.
|
||||
|
||||
config MTK_DEVAPC
|
||||
tristate "Mediatek Device APC Support"
|
||||
help
|
||||
Say yes here to enable support for Mediatek Device APC driver.
|
||||
This driver is mainly used to handle the violation which catches
|
||||
unexpected transaction.
|
||||
The violation information is logged for further analysis or
|
||||
countermeasures.
|
||||
|
||||
config MTK_INFRACFG
|
||||
bool "MediaTek INFRACFG Support"
|
||||
select REGMAP
|
||||
|
@ -44,6 +53,18 @@ config MTK_SCPSYS
|
|||
Say yes here to add support for the MediaTek SCPSYS power domain
|
||||
driver.
|
||||
|
||||
config MTK_SCPSYS_PM_DOMAINS
|
||||
bool "MediaTek SCPSYS generic power domain"
|
||||
default ARCH_MEDIATEK
|
||||
depends on PM
|
||||
select PM_GENERIC_DOMAINS
|
||||
select REGMAP
|
||||
help
|
||||
Say y here to enable power domain support.
|
||||
In order to meet high performance and low power requirements, the System
|
||||
Control Processor System (SCPSYS) has several power management related
|
||||
tasks in the system.
|
||||
|
||||
config MTK_MMSYS
|
||||
bool "MediaTek MMSYS Support"
|
||||
default ARCH_MEDIATEK
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
|
||||
obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o
|
||||
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
|
||||
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
|
||||
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
|
||||
obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
|
||||
obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8173_PM_DOMAINS_H
|
||||
#define __SOC_MEDIATEK_MT8173_PM_DOMAINS_H
|
||||
|
||||
#include "mtk-pm-domains.h"
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
/*
|
||||
* MT8173 power domain support
|
||||
*/
|
||||
|
||||
static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
|
||||
[MT8173_POWER_DOMAIN_VDEC] = {
|
||||
.sta_mask = PWR_STATUS_VDEC,
|
||||
.ctl_offs = SPM_VDE_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_VENC] = {
|
||||
.sta_mask = PWR_STATUS_VENC,
|
||||
.ctl_offs = SPM_VEN_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_ISP] = {
|
||||
.sta_mask = PWR_STATUS_ISP,
|
||||
.ctl_offs = SPM_ISP_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MM] = {
|
||||
.sta_mask = PWR_STATUS_DISP,
|
||||
.ctl_offs = SPM_DIS_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 |
|
||||
MT8173_TOP_AXI_PROT_EN_MM_M1),
|
||||
},
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_VENC_LT] = {
|
||||
.sta_mask = PWR_STATUS_VENC_LT,
|
||||
.ctl_offs = SPM_VEN2_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_AUDIO] = {
|
||||
.sta_mask = PWR_STATUS_AUDIO,
|
||||
.ctl_offs = SPM_AUDIO_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_USB] = {
|
||||
.sta_mask = PWR_STATUS_USB,
|
||||
.ctl_offs = SPM_USB_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.caps = MTK_SCPD_ACTIVE_WAKEUP,
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MFG_ASYNC] = {
|
||||
.sta_mask = PWR_STATUS_MFG_ASYNC,
|
||||
.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = 0,
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MFG_2D] = {
|
||||
.sta_mask = PWR_STATUS_MFG_2D,
|
||||
.ctl_offs = SPM_MFG_2D_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
},
|
||||
[MT8173_POWER_DOMAIN_MFG] = {
|
||||
.sta_mask = PWR_STATUS_MFG,
|
||||
.ctl_offs = SPM_MFG_PWR_CON,
|
||||
.sram_pdn_bits = GENMASK(13, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(21, 16),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S |
|
||||
MT8173_TOP_AXI_PROT_EN_MFG_M0 |
|
||||
MT8173_TOP_AXI_PROT_EN_MFG_M1 |
|
||||
MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8173_scpsys_data = {
|
||||
.domains_data = scpsys_domain_data_mt8173,
|
||||
.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
|
||||
.pwr_sta_offs = SPM_PWR_STATUS,
|
||||
.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
|
|
@ -0,0 +1,221 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8183_PM_DOMAINS_H
|
||||
#define __SOC_MEDIATEK_MT8183_PM_DOMAINS_H
|
||||
|
||||
#include "mtk-pm-domains.h"
|
||||
#include <dt-bindings/power/mt8183-power.h>
|
||||
|
||||
/*
|
||||
* MT8183 power domain support
|
||||
*/
|
||||
|
||||
static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
|
||||
[MT8183_POWER_DOMAIN_AUDIO] = {
|
||||
.sta_mask = PWR_STATUS_AUDIO,
|
||||
.ctl_offs = 0x0314,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_CONN] = {
|
||||
.sta_mask = PWR_STATUS_CONN,
|
||||
.ctl_offs = 0x032c,
|
||||
.sram_pdn_bits = 0,
|
||||
.sram_pdn_ack_bits = 0,
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_CONN, MT8183_TOP_AXI_PROT_EN_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_MFG_ASYNC] = {
|
||||
.sta_mask = PWR_STATUS_MFG_ASYNC,
|
||||
.ctl_offs = 0x0334,
|
||||
.sram_pdn_bits = 0,
|
||||
.sram_pdn_ack_bits = 0,
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_MFG] = {
|
||||
.sta_mask = PWR_STATUS_MFG,
|
||||
.ctl_offs = 0x0338,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_MFG_CORE0] = {
|
||||
.sta_mask = BIT(7),
|
||||
.ctl_offs = 0x034c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_MFG_CORE1] = {
|
||||
.sta_mask = BIT(20),
|
||||
.ctl_offs = 0x0310,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_MFG_2D] = {
|
||||
.sta_mask = PWR_STATUS_MFG_2D,
|
||||
.ctl_offs = 0x0348,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_1_MFG, MT8183_TOP_AXI_PROT_EN_1_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_1_CLR, MT8183_TOP_AXI_PROT_EN_STA1_1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MFG, MT8183_TOP_AXI_PROT_EN_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_DISP] = {
|
||||
.sta_mask = PWR_STATUS_DISP,
|
||||
.ctl_offs = 0x030c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_1_DISP, MT8183_TOP_AXI_PROT_EN_1_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_1_CLR, MT8183_TOP_AXI_PROT_EN_STA1_1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_DISP, MT8183_TOP_AXI_PROT_EN_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
|
||||
},
|
||||
.bp_smi = {
|
||||
BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_DISP,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_SET,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_CLR,
|
||||
MT8183_SMI_COMMON_CLAMP_EN),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_CAM] = {
|
||||
.sta_mask = BIT(25),
|
||||
.ctl_offs = 0x0344,
|
||||
.sram_pdn_bits = GENMASK(9, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_CAM, MT8183_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_CLR, MT8183_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_CAM, MT8183_TOP_AXI_PROT_EN_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_CLR, MT8183_TOP_AXI_PROT_EN_STA1),
|
||||
BUS_PROT_WR_IGN(MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
.bp_smi = {
|
||||
BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_CAM,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_SET,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_CLR,
|
||||
MT8183_SMI_COMMON_CLAMP_EN),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_ISP] = {
|
||||
.sta_mask = PWR_STATUS_ISP,
|
||||
.ctl_offs = 0x0308,
|
||||
.sram_pdn_bits = GENMASK(9, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_ISP,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR_IGN(MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
.bp_smi = {
|
||||
BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_ISP,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_SET,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_CLR,
|
||||
MT8183_SMI_COMMON_CLAMP_EN),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_VDEC] = {
|
||||
.sta_mask = BIT(31),
|
||||
.ctl_offs = 0x0300,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_smi = {
|
||||
BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VDEC,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_SET,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_CLR,
|
||||
MT8183_SMI_COMMON_CLAMP_EN),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_VENC] = {
|
||||
.sta_mask = PWR_STATUS_VENC,
|
||||
.ctl_offs = 0x0304,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
.bp_smi = {
|
||||
BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VENC,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_SET,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_CLR,
|
||||
MT8183_SMI_COMMON_CLAMP_EN),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_VPU_TOP] = {
|
||||
.sta_mask = BIT(26),
|
||||
.ctl_offs = 0x0324,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_VPU_TOP,
|
||||
MT8183_TOP_AXI_PROT_EN_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_STA1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
.bp_smi = {
|
||||
BUS_PROT_WR(MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_SET,
|
||||
MT8183_SMI_COMMON_CLAMP_EN_CLR,
|
||||
MT8183_SMI_COMMON_CLAMP_EN),
|
||||
},
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_VPU_CORE0] = {
|
||||
.sta_mask = BIT(27),
|
||||
.ctl_offs = 0x33c,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
|
||||
},
|
||||
.caps = MTK_SCPD_SRAM_ISO,
|
||||
},
|
||||
[MT8183_POWER_DOMAIN_VPU_CORE1] = {
|
||||
.sta_mask = BIT(28),
|
||||
.ctl_offs = 0x0340,
|
||||
.sram_pdn_bits = GENMASK(11, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
|
||||
BUS_PROT_WR(MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_SET,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_CLR,
|
||||
MT8183_TOP_AXI_PROT_EN_MCU_STA1),
|
||||
},
|
||||
.caps = MTK_SCPD_SRAM_ISO,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8183_scpsys_data = {
|
||||
.domains_data = scpsys_domain_data_mt8183,
|
||||
.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
|
||||
.pwr_sta_offs = 0x0180,
|
||||
.pwr_sta2nd_offs = 0x0184
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
|
|
@ -0,0 +1,292 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MT8192_PM_DOMAINS_H
|
||||
#define __SOC_MEDIATEK_MT8192_PM_DOMAINS_H
|
||||
|
||||
#include "mtk-pm-domains.h"
|
||||
#include <dt-bindings/power/mt8192-power.h>
|
||||
|
||||
/*
|
||||
* MT8192 power domain support
|
||||
*/
|
||||
|
||||
static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
|
||||
[MT8192_POWER_DOMAIN_AUDIO] = {
|
||||
.sta_mask = BIT(21),
|
||||
.ctl_offs = 0x0354,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_AUDIO,
|
||||
MT8192_TOP_AXI_PROT_EN_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_2_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_CONN] = {
|
||||
.sta_mask = PWR_STATUS_CONN,
|
||||
.ctl_offs = 0x0304,
|
||||
.sram_pdn_bits = 0,
|
||||
.sram_pdn_ack_bits = 0,
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_CONN,
|
||||
MT8192_TOP_AXI_PROT_EN_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_CONN_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_CONN,
|
||||
MT8192_TOP_AXI_PROT_EN_1_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_1_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_1_STA1),
|
||||
},
|
||||
.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG0] = {
|
||||
.sta_mask = BIT(2),
|
||||
.ctl_offs = 0x0308,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG1] = {
|
||||
.sta_mask = BIT(3),
|
||||
.ctl_offs = 0x030c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_MFG1,
|
||||
MT8192_TOP_AXI_PROT_EN_1_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_1_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_1_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_MFG1,
|
||||
MT8192_TOP_AXI_PROT_EN_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_2_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MFG1,
|
||||
MT8192_TOP_AXI_PROT_EN_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_MFG1_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_2_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG2] = {
|
||||
.sta_mask = BIT(4),
|
||||
.ctl_offs = 0x0310,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG3] = {
|
||||
.sta_mask = BIT(5),
|
||||
.ctl_offs = 0x0314,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG4] = {
|
||||
.sta_mask = BIT(6),
|
||||
.ctl_offs = 0x0318,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG5] = {
|
||||
.sta_mask = BIT(7),
|
||||
.ctl_offs = 0x031c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MFG6] = {
|
||||
.sta_mask = BIT(8),
|
||||
.ctl_offs = 0x0320,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_DISP] = {
|
||||
.sta_mask = BIT(20),
|
||||
.ctl_offs = 0x0350,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR_IGN(MT8192_TOP_AXI_PROT_EN_MM_DISP,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR_IGN(MT8192_TOP_AXI_PROT_EN_MM_2_DISP,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_DISP,
|
||||
MT8192_TOP_AXI_PROT_EN_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_DISP_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_DISP_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_IPE] = {
|
||||
.sta_mask = BIT(14),
|
||||
.ctl_offs = 0x0338,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_IPE,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_IPE_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_ISP] = {
|
||||
.sta_mask = BIT(12),
|
||||
.ctl_offs = 0x0330,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_ISP,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_ISP_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_ISP2] = {
|
||||
.sta_mask = BIT(13),
|
||||
.ctl_offs = 0x0334,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_ISP2,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_ISP2_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_MDP] = {
|
||||
.sta_mask = BIT(19),
|
||||
.ctl_offs = 0x034c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_MDP,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_2_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_VENC] = {
|
||||
.sta_mask = BIT(17),
|
||||
.ctl_offs = 0x0344,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VENC,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VENC_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_VDEC] = {
|
||||
.sta_mask = BIT(15),
|
||||
.ctl_offs = 0x033c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VDEC,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_VDEC_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_VDEC2] = {
|
||||
.sta_mask = BIT(16),
|
||||
.ctl_offs = 0x0340,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_CAM] = {
|
||||
.sta_mask = BIT(23),
|
||||
.ctl_offs = 0x035c,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
.bp_infracfg = {
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_2_CAM,
|
||||
MT8192_TOP_AXI_PROT_EN_2_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_2_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_2_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_CAM,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_1_CAM,
|
||||
MT8192_TOP_AXI_PROT_EN_1_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_1_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_1_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_MM_CAM_2ND,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_MM_STA1),
|
||||
BUS_PROT_WR(MT8192_TOP_AXI_PROT_EN_VDNR_CAM,
|
||||
MT8192_TOP_AXI_PROT_EN_VDNR_SET,
|
||||
MT8192_TOP_AXI_PROT_EN_VDNR_CLR,
|
||||
MT8192_TOP_AXI_PROT_EN_VDNR_STA1),
|
||||
},
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_CAM_RAWA] = {
|
||||
.sta_mask = BIT(24),
|
||||
.ctl_offs = 0x0360,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_CAM_RAWB] = {
|
||||
.sta_mask = BIT(25),
|
||||
.ctl_offs = 0x0364,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
[MT8192_POWER_DOMAIN_CAM_RAWC] = {
|
||||
.sta_mask = BIT(26),
|
||||
.ctl_offs = 0x0368,
|
||||
.sram_pdn_bits = GENMASK(8, 8),
|
||||
.sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct scpsys_soc_data mt8192_scpsys_data = {
|
||||
.domains_data = scpsys_domain_data_mt8192,
|
||||
.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
|
||||
.pwr_sta_offs = 0x016c,
|
||||
.pwr_sta2nd_offs = 0x0170,
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
|
|
@ -70,14 +70,7 @@ int cmdq_dev_get_client_reg(struct device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL(cmdq_dev_get_client_reg);
|
||||
|
||||
static void cmdq_client_timeout(struct timer_list *t)
|
||||
{
|
||||
struct cmdq_client *client = from_timer(client, t, timer);
|
||||
|
||||
dev_err(client->client.dev, "cmdq timeout!\n");
|
||||
}
|
||||
|
||||
struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout)
|
||||
struct cmdq_client *cmdq_mbox_create(struct device *dev, int index)
|
||||
{
|
||||
struct cmdq_client *client;
|
||||
|
||||
|
@ -85,12 +78,6 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, int index, u32 timeout)
|
|||
if (!client)
|
||||
return (struct cmdq_client *)-ENOMEM;
|
||||
|
||||
client->timeout_ms = timeout;
|
||||
if (timeout != CMDQ_NO_TIMEOUT) {
|
||||
spin_lock_init(&client->lock);
|
||||
timer_setup(&client->timer, cmdq_client_timeout, 0);
|
||||
}
|
||||
client->pkt_cnt = 0;
|
||||
client->client.dev = dev;
|
||||
client->client.tx_block = false;
|
||||
client->client.knows_txdone = true;
|
||||
|
@ -112,11 +99,6 @@ EXPORT_SYMBOL(cmdq_mbox_create);
|
|||
|
||||
void cmdq_mbox_destroy(struct cmdq_client *client)
|
||||
{
|
||||
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
|
||||
spin_lock(&client->lock);
|
||||
del_timer_sync(&client->timer);
|
||||
spin_unlock(&client->lock);
|
||||
}
|
||||
mbox_free_channel(client->chan);
|
||||
kfree(client);
|
||||
}
|
||||
|
@ -449,18 +431,6 @@ static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
|
|||
struct cmdq_task_cb *cb = &pkt->cb;
|
||||
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
|
||||
|
||||
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock_irqsave(&client->lock, flags);
|
||||
if (--client->pkt_cnt == 0)
|
||||
del_timer(&client->timer);
|
||||
else
|
||||
mod_timer(&client->timer, jiffies +
|
||||
msecs_to_jiffies(client->timeout_ms));
|
||||
spin_unlock_irqrestore(&client->lock, flags);
|
||||
}
|
||||
|
||||
dma_sync_single_for_cpu(client->chan->mbox->dev, pkt->pa_base,
|
||||
pkt->cmd_buf_size, DMA_TO_DEVICE);
|
||||
if (cb->cb) {
|
||||
|
@ -473,7 +443,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
|
|||
void *data)
|
||||
{
|
||||
int err;
|
||||
unsigned long flags = 0;
|
||||
struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
|
||||
|
||||
pkt->cb.cb = cb;
|
||||
|
@ -484,14 +453,6 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
|
|||
dma_sync_single_for_device(client->chan->mbox->dev, pkt->pa_base,
|
||||
pkt->cmd_buf_size, DMA_TO_DEVICE);
|
||||
|
||||
if (client->timeout_ms != CMDQ_NO_TIMEOUT) {
|
||||
spin_lock_irqsave(&client->lock, flags);
|
||||
if (client->pkt_cnt++ == 0)
|
||||
mod_timer(&client->timer, jiffies +
|
||||
msecs_to_jiffies(client->timeout_ms));
|
||||
spin_unlock_irqrestore(&client->lock, flags);
|
||||
}
|
||||
|
||||
err = mbox_send_message(client->chan, pkt);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2020 MediaTek Inc.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#define VIO_MOD_TO_REG_IND(m) ((m) / 32)
|
||||
#define VIO_MOD_TO_REG_OFF(m) ((m) % 32)
|
||||
|
||||
struct mtk_devapc_vio_dbgs {
|
||||
union {
|
||||
u32 vio_dbg0;
|
||||
struct {
|
||||
u32 mstid:16;
|
||||
u32 dmnid:6;
|
||||
u32 vio_w:1;
|
||||
u32 vio_r:1;
|
||||
u32 addr_h:4;
|
||||
u32 resv:4;
|
||||
} dbg0_bits;
|
||||
};
|
||||
|
||||
u32 vio_dbg1;
|
||||
};
|
||||
|
||||
struct mtk_devapc_data {
|
||||
/* numbers of violation index */
|
||||
u32 vio_idx_num;
|
||||
|
||||
/* reg offset */
|
||||
u32 vio_mask_offset;
|
||||
u32 vio_sta_offset;
|
||||
u32 vio_dbg0_offset;
|
||||
u32 vio_dbg1_offset;
|
||||
u32 apc_con_offset;
|
||||
u32 vio_shift_sta_offset;
|
||||
u32 vio_shift_sel_offset;
|
||||
u32 vio_shift_con_offset;
|
||||
};
|
||||
|
||||
struct mtk_devapc_context {
|
||||
struct device *dev;
|
||||
void __iomem *infra_base;
|
||||
struct clk *infra_clk;
|
||||
const struct mtk_devapc_data *data;
|
||||
};
|
||||
|
||||
static void clear_vio_status(struct mtk_devapc_context *ctx)
|
||||
{
|
||||
void __iomem *reg;
|
||||
int i;
|
||||
|
||||
reg = ctx->infra_base + ctx->data->vio_sta_offset;
|
||||
|
||||
for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++)
|
||||
writel(GENMASK(31, 0), reg + 4 * i);
|
||||
|
||||
writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0),
|
||||
reg + 4 * i);
|
||||
}
|
||||
|
||||
static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
reg = ctx->infra_base + ctx->data->vio_mask_offset;
|
||||
|
||||
if (mask)
|
||||
val = GENMASK(31, 0);
|
||||
else
|
||||
val = 0;
|
||||
|
||||
for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1; i++)
|
||||
writel(val, reg + 4 * i);
|
||||
|
||||
val = readl(reg + 4 * i);
|
||||
if (mask)
|
||||
val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1,
|
||||
0);
|
||||
else
|
||||
val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1,
|
||||
0);
|
||||
|
||||
writel(val, reg + 4 * i);
|
||||
}
|
||||
|
||||
#define PHY_DEVAPC_TIMEOUT 0x10000
|
||||
|
||||
/*
|
||||
* devapc_sync_vio_dbg - do "shift" mechansim" to get full violation information.
|
||||
* shift mechanism is depends on devapc hardware design.
|
||||
* Mediatek devapc set multiple slaves as a group.
|
||||
* When violation is triggered, violation info is kept
|
||||
* inside devapc hardware.
|
||||
* Driver should do shift mechansim to sync full violation
|
||||
* info to VIO_DBGs registers.
|
||||
*
|
||||
*/
|
||||
static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx)
|
||||
{
|
||||
void __iomem *pd_vio_shift_sta_reg;
|
||||
void __iomem *pd_vio_shift_sel_reg;
|
||||
void __iomem *pd_vio_shift_con_reg;
|
||||
int min_shift_group;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
pd_vio_shift_sta_reg = ctx->infra_base +
|
||||
ctx->data->vio_shift_sta_offset;
|
||||
pd_vio_shift_sel_reg = ctx->infra_base +
|
||||
ctx->data->vio_shift_sel_offset;
|
||||
pd_vio_shift_con_reg = ctx->infra_base +
|
||||
ctx->data->vio_shift_con_offset;
|
||||
|
||||
/* Find the minimum shift group which has violation */
|
||||
val = readl(pd_vio_shift_sta_reg);
|
||||
if (!val)
|
||||
return false;
|
||||
|
||||
min_shift_group = __ffs(val);
|
||||
|
||||
/* Assign the group to sync */
|
||||
writel(0x1 << min_shift_group, pd_vio_shift_sel_reg);
|
||||
|
||||
/* Start syncing */
|
||||
writel(0x1, pd_vio_shift_con_reg);
|
||||
|
||||
ret = readl_poll_timeout(pd_vio_shift_con_reg, val, val == 0x3, 0,
|
||||
PHY_DEVAPC_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(ctx->dev, "%s: Shift violation info failed\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Stop syncing */
|
||||
writel(0x0, pd_vio_shift_con_reg);
|
||||
|
||||
/* Write clear */
|
||||
writel(0x1 << min_shift_group, pd_vio_shift_sta_reg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* devapc_extract_vio_dbg - extract full violation information after doing
|
||||
* shift mechanism.
|
||||
*/
|
||||
static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx)
|
||||
{
|
||||
struct mtk_devapc_vio_dbgs vio_dbgs;
|
||||
void __iomem *vio_dbg0_reg;
|
||||
void __iomem *vio_dbg1_reg;
|
||||
|
||||
vio_dbg0_reg = ctx->infra_base + ctx->data->vio_dbg0_offset;
|
||||
vio_dbg1_reg = ctx->infra_base + ctx->data->vio_dbg1_offset;
|
||||
|
||||
vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg);
|
||||
vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg);
|
||||
|
||||
/* Print violation information */
|
||||
if (vio_dbgs.dbg0_bits.vio_w)
|
||||
dev_info(ctx->dev, "Write Violation\n");
|
||||
else if (vio_dbgs.dbg0_bits.vio_r)
|
||||
dev_info(ctx->dev, "Read Violation\n");
|
||||
|
||||
dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n",
|
||||
vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid,
|
||||
vio_dbgs.vio_dbg1);
|
||||
}
|
||||
|
||||
/*
|
||||
* devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump
|
||||
* violation information including which master violates
|
||||
* access slave.
|
||||
*/
|
||||
static irqreturn_t devapc_violation_irq(int irq_number, void *data)
|
||||
{
|
||||
struct mtk_devapc_context *ctx = data;
|
||||
|
||||
while (devapc_sync_vio_dbg(ctx))
|
||||
devapc_extract_vio_dbg(ctx);
|
||||
|
||||
clear_vio_status(ctx);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* start_devapc - unmask slave's irq to start receiving devapc violation.
|
||||
*/
|
||||
static void start_devapc(struct mtk_devapc_context *ctx)
|
||||
{
|
||||
writel(BIT(31), ctx->infra_base + ctx->data->apc_con_offset);
|
||||
|
||||
mask_module_irq(ctx, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* stop_devapc - mask slave's irq to stop service.
|
||||
*/
|
||||
static void stop_devapc(struct mtk_devapc_context *ctx)
|
||||
{
|
||||
mask_module_irq(ctx, true);
|
||||
|
||||
writel(BIT(2), ctx->infra_base + ctx->data->apc_con_offset);
|
||||
}
|
||||
|
||||
static const struct mtk_devapc_data devapc_mt6779 = {
|
||||
.vio_idx_num = 511,
|
||||
.vio_mask_offset = 0x0,
|
||||
.vio_sta_offset = 0x400,
|
||||
.vio_dbg0_offset = 0x900,
|
||||
.vio_dbg1_offset = 0x904,
|
||||
.apc_con_offset = 0xF00,
|
||||
.vio_shift_sta_offset = 0xF10,
|
||||
.vio_shift_sel_offset = 0xF14,
|
||||
.vio_shift_con_offset = 0xF20,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_devapc_dt_match[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt6779-devapc",
|
||||
.data = &devapc_mt6779,
|
||||
}, {
|
||||
},
|
||||
};
|
||||
|
||||
static int mtk_devapc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct mtk_devapc_context *ctx;
|
||||
u32 devapc_irq;
|
||||
int ret;
|
||||
|
||||
if (IS_ERR(node))
|
||||
return -ENODEV;
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->data = of_device_get_match_data(&pdev->dev);
|
||||
ctx->dev = &pdev->dev;
|
||||
|
||||
ctx->infra_base = of_iomap(node, 0);
|
||||
if (!ctx->infra_base)
|
||||
return -EINVAL;
|
||||
|
||||
devapc_irq = irq_of_parse_and_map(node, 0);
|
||||
if (!devapc_irq)
|
||||
return -EINVAL;
|
||||
|
||||
ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock");
|
||||
if (IS_ERR(ctx->infra_clk))
|
||||
return -EINVAL;
|
||||
|
||||
if (clk_prepare_enable(ctx->infra_clk))
|
||||
return -EINVAL;
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq,
|
||||
IRQF_TRIGGER_NONE, "devapc", ctx);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(ctx->infra_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ctx);
|
||||
|
||||
start_devapc(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_devapc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
|
||||
|
||||
stop_devapc(ctx);
|
||||
|
||||
clk_disable_unprepare(ctx->infra_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mtk_devapc_driver = {
|
||||
.probe = mtk_devapc_probe,
|
||||
.remove = mtk_devapc_remove,
|
||||
.driver = {
|
||||
.name = "mtk-devapc",
|
||||
.of_match_table = mtk_devapc_dt_match,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(mtk_devapc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Mediatek Device APC Driver");
|
||||
MODULE_AUTHOR("Neal Liu <neal.liu@mediatek.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -12,11 +12,6 @@
|
|||
#define MTK_POLL_DELAY_US 10
|
||||
#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
|
||||
|
||||
#define INFRA_TOPAXI_PROTECTEN 0x0220
|
||||
#define INFRA_TOPAXI_PROTECTSTA1 0x0228
|
||||
#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
|
||||
#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
|
||||
|
||||
/**
|
||||
* mtk_infracfg_set_bus_protection - enable bus protection
|
||||
* @infracfg: The infracfg regmap
|
||||
|
|
|
@ -5,13 +5,11 @@
|
|||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/soc/mediatek/mtk-mmsys.h>
|
||||
|
||||
#include "../../gpu/drm/mediatek/mtk_drm_ddp.h"
|
||||
#include "../../gpu/drm/mediatek/mtk_drm_ddp_comp.h"
|
||||
|
||||
#define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x040
|
||||
#define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN 0x044
|
||||
#define DISP_REG_CONFIG_DISP_OD_MOUT_EN 0x048
|
||||
|
@ -308,15 +306,12 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
|
|||
struct platform_device *clks;
|
||||
struct platform_device *drm;
|
||||
void __iomem *config_regs;
|
||||
struct resource *mem;
|
||||
int ret;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
config_regs = devm_ioremap_resource(dev, mem);
|
||||
config_regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(config_regs)) {
|
||||
ret = PTR_ERR(config_regs);
|
||||
dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
|
||||
ret);
|
||||
dev_err(dev, "Failed to ioremap mmsys registers: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,614 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020 Collabora Ltd.
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/soc/mediatek/infracfg.h>
|
||||
|
||||
#include "mt8173-pm-domains.h"
|
||||
#include "mt8183-pm-domains.h"
|
||||
#include "mt8192-pm-domains.h"
|
||||
|
||||
#define MTK_POLL_DELAY_US 10
|
||||
#define MTK_POLL_TIMEOUT USEC_PER_SEC
|
||||
|
||||
#define PWR_RST_B_BIT BIT(0)
|
||||
#define PWR_ISO_BIT BIT(1)
|
||||
#define PWR_ON_BIT BIT(2)
|
||||
#define PWR_ON_2ND_BIT BIT(3)
|
||||
#define PWR_CLK_DIS_BIT BIT(4)
|
||||
#define PWR_SRAM_CLKISO_BIT BIT(5)
|
||||
#define PWR_SRAM_ISOINT_B_BIT BIT(6)
|
||||
|
||||
struct scpsys_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
const struct scpsys_domain_data *data;
|
||||
struct scpsys *scpsys;
|
||||
int num_clks;
|
||||
struct clk_bulk_data *clks;
|
||||
int num_subsys_clks;
|
||||
struct clk_bulk_data *subsys_clks;
|
||||
struct regmap *infracfg;
|
||||
struct regmap *smi;
|
||||
};
|
||||
|
||||
struct scpsys {
|
||||
struct device *dev;
|
||||
struct regmap *base;
|
||||
const struct scpsys_soc_data *soc_data;
|
||||
struct genpd_onecell_data pd_data;
|
||||
struct generic_pm_domain *domains[];
|
||||
};
|
||||
|
||||
#define to_scpsys_domain(gpd) container_of(gpd, struct scpsys_domain, genpd)
|
||||
|
||||
static bool scpsys_domain_is_on(struct scpsys_domain *pd)
|
||||
{
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
u32 status, status2;
|
||||
|
||||
regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status);
|
||||
status &= pd->data->sta_mask;
|
||||
|
||||
regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2);
|
||||
status2 &= pd->data->sta_mask;
|
||||
|
||||
/* A domain is on when both status bits are set. */
|
||||
return status && status2;
|
||||
}
|
||||
|
||||
static int scpsys_sram_enable(struct scpsys_domain *pd)
|
||||
{
|
||||
u32 pdn_ack = pd->data->sram_pdn_ack_bits;
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
unsigned int tmp;
|
||||
int ret;
|
||||
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
|
||||
|
||||
/* Either wait until SRAM_PDN_ACK all 1 or 0 */
|
||||
ret = regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp,
|
||||
(tmp & pdn_ack) == 0, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_ISO)) {
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT);
|
||||
udelay(1);
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_CLKISO_BIT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_sram_disable(struct scpsys_domain *pd)
|
||||
{
|
||||
u32 pdn_ack = pd->data->sram_pdn_ack_bits;
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
unsigned int tmp;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_ISO)) {
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_CLKISO_BIT);
|
||||
udelay(1);
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT);
|
||||
}
|
||||
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
|
||||
|
||||
/* Either wait until SRAM_PDN_ACK all 1 or 0 */
|
||||
return regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp,
|
||||
(tmp & pdn_ack) == pdn_ack, MTK_POLL_DELAY_US,
|
||||
MTK_POLL_TIMEOUT);
|
||||
}
|
||||
|
||||
static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd, struct regmap *regmap)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
|
||||
u32 val, mask = bpd[i].bus_prot_mask;
|
||||
|
||||
if (!mask)
|
||||
break;
|
||||
|
||||
if (bpd[i].bus_prot_reg_update)
|
||||
regmap_set_bits(regmap, bpd[i].bus_prot_set, mask);
|
||||
else
|
||||
regmap_write(regmap, bpd[i].bus_prot_set, mask);
|
||||
|
||||
ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
|
||||
val, (val & mask) == mask,
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg, pd->infracfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return _scpsys_bus_protect_enable(pd->data->bp_smi, pd->smi);
|
||||
}
|
||||
|
||||
static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
|
||||
u32 val, mask = bpd[i].bus_prot_mask;
|
||||
|
||||
if (!mask)
|
||||
continue;
|
||||
|
||||
if (bpd[i].bus_prot_reg_update)
|
||||
regmap_clear_bits(regmap, bpd[i].bus_prot_clr, mask);
|
||||
else
|
||||
regmap_write(regmap, bpd[i].bus_prot_clr, mask);
|
||||
|
||||
if (bpd[i].ignore_clr_ack)
|
||||
continue;
|
||||
|
||||
ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
|
||||
val, !(val & mask),
|
||||
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _scpsys_bus_protect_disable(pd->data->bp_smi, pd->smi);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg);
|
||||
}
|
||||
|
||||
static int scpsys_power_on(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
||||
ret = clk_bulk_enable(pd->num_clks, pd->clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* subsys power on */
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
|
||||
|
||||
/* wait until PWR_ACK = 1 */
|
||||
ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US,
|
||||
MTK_POLL_TIMEOUT);
|
||||
if (ret < 0)
|
||||
goto err_pwr_ack;
|
||||
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
|
||||
ret = clk_bulk_enable(pd->num_subsys_clks, pd->subsys_clks);
|
||||
if (ret)
|
||||
goto err_pwr_ack;
|
||||
|
||||
ret = scpsys_sram_enable(pd);
|
||||
if (ret < 0)
|
||||
goto err_disable_subsys_clks;
|
||||
|
||||
ret = scpsys_bus_protect_disable(pd);
|
||||
if (ret < 0)
|
||||
goto err_disable_sram;
|
||||
|
||||
return 0;
|
||||
|
||||
err_disable_sram:
|
||||
scpsys_sram_disable(pd);
|
||||
err_disable_subsys_clks:
|
||||
clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks);
|
||||
err_pwr_ack:
|
||||
clk_bulk_disable(pd->num_clks, pd->clks);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scpsys_power_off(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
|
||||
struct scpsys *scpsys = pd->scpsys;
|
||||
bool tmp;
|
||||
int ret;
|
||||
|
||||
ret = scpsys_bus_protect_enable(pd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = scpsys_sram_disable(pd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks);
|
||||
|
||||
/* subsys power off */
|
||||
regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
|
||||
regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_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;
|
||||
|
||||
clk_bulk_disable(pd->num_clks, pd->clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct
|
||||
generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_node *node)
|
||||
{
|
||||
const struct scpsys_domain_data *domain_data;
|
||||
struct scpsys_domain *pd;
|
||||
struct property *prop;
|
||||
const char *clk_name;
|
||||
int i, ret, num_clks;
|
||||
struct clk *clk;
|
||||
int clk_ind = 0;
|
||||
u32 id;
|
||||
|
||||
ret = of_property_read_u32(node, "reg", &id);
|
||||
if (ret) {
|
||||
dev_err(scpsys->dev, "%pOF: failed to retrieve domain id from reg: %d\n",
|
||||
node, ret);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
pd = devm_kzalloc(scpsys->dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pd->data = domain_data;
|
||||
pd->scpsys = scpsys;
|
||||
|
||||
pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg");
|
||||
if (IS_ERR(pd->infracfg))
|
||||
return ERR_CAST(pd->infracfg);
|
||||
|
||||
pd->smi = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,smi");
|
||||
if (IS_ERR(pd->smi))
|
||||
return ERR_CAST(pd->smi);
|
||||
|
||||
num_clks = of_clk_get_parent_count(node);
|
||||
if (num_clks > 0) {
|
||||
/* Calculate number of subsys_clks */
|
||||
of_property_for_each_string(node, "clock-names", prop, clk_name) {
|
||||
char *subsys;
|
||||
|
||||
subsys = strchr(clk_name, '-');
|
||||
if (subsys)
|
||||
pd->num_subsys_clks++;
|
||||
else
|
||||
pd->num_clks++;
|
||||
}
|
||||
|
||||
pd->clks = devm_kcalloc(scpsys->dev, pd->num_clks, sizeof(*pd->clks), GFP_KERNEL);
|
||||
if (!pd->clks)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pd->subsys_clks = devm_kcalloc(scpsys->dev, pd->num_subsys_clks,
|
||||
sizeof(*pd->subsys_clks), GFP_KERNEL);
|
||||
if (!pd->subsys_clks)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < pd->num_clks; i++) {
|
||||
clk = of_clk_get(node, i);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
dev_err_probe(scpsys->dev, ret,
|
||||
"%pOF: failed to get clk at index %d: %d\n", node, i, ret);
|
||||
goto err_put_clocks;
|
||||
}
|
||||
|
||||
pd->clks[clk_ind++].clk = clk;
|
||||
}
|
||||
|
||||
for (i = 0; i < pd->num_subsys_clks; i++) {
|
||||
clk = of_clk_get(node, i + clk_ind);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
dev_err_probe(scpsys->dev, ret,
|
||||
"%pOF: failed to get clk at index %d: %d\n", node,
|
||||
i + clk_ind, ret);
|
||||
goto err_put_subsys_clocks;
|
||||
}
|
||||
|
||||
pd->subsys_clks[i].clk = clk;
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare(pd->num_clks, pd->clks);
|
||||
if (ret)
|
||||
goto err_put_subsys_clocks;
|
||||
|
||||
ret = clk_bulk_prepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
if (ret)
|
||||
goto err_unprepare_clocks;
|
||||
|
||||
/*
|
||||
* Initially turn on all domains to make the domains usable
|
||||
* with !CONFIG_PM and to get the hardware in sync with the
|
||||
* software. The unused domains will be switched off during
|
||||
* late_init time.
|
||||
*/
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF)) {
|
||||
if (scpsys_domain_is_on(pd))
|
||||
dev_warn(scpsys->dev,
|
||||
"%pOF: A default off power domain has been ON\n", node);
|
||||
} else {
|
||||
ret = scpsys_power_on(&pd->genpd);
|
||||
if (ret < 0) {
|
||||
dev_err(scpsys->dev, "%pOF: failed to power on domain: %d\n", node, ret);
|
||||
goto err_unprepare_clocks;
|
||||
}
|
||||
}
|
||||
|
||||
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_unprepare_subsys_clocks;
|
||||
}
|
||||
|
||||
pd->genpd.name = node->name;
|
||||
pd->genpd.power_off = scpsys_power_off;
|
||||
pd->genpd.power_on = scpsys_power_on;
|
||||
|
||||
if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF))
|
||||
pm_genpd_init(&pd->genpd, NULL, true);
|
||||
else
|
||||
pm_genpd_init(&pd->genpd, NULL, false);
|
||||
|
||||
scpsys->domains[id] = &pd->genpd;
|
||||
|
||||
return scpsys->pd_data.domains[id];
|
||||
|
||||
err_unprepare_subsys_clocks:
|
||||
clk_bulk_unprepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
err_unprepare_clocks:
|
||||
clk_bulk_unprepare(pd->num_clks, pd->clks);
|
||||
err_put_subsys_clocks:
|
||||
clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks);
|
||||
err_put_clocks:
|
||||
clk_bulk_put(pd->num_clks, pd->clks);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *parent)
|
||||
{
|
||||
struct generic_pm_domain *child_pd, *parent_pd;
|
||||
struct device_node *child;
|
||||
int ret;
|
||||
|
||||
for_each_child_of_node(parent, child) {
|
||||
u32 id;
|
||||
|
||||
ret = of_property_read_u32(parent, "reg", &id);
|
||||
if (ret) {
|
||||
dev_err(scpsys->dev, "%pOF: failed to get parent domain id\n", child);
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
if (!scpsys->pd_data.domains[id]) {
|
||||
ret = -EINVAL;
|
||||
dev_err(scpsys->dev, "power domain with id %d does not exist\n", id);
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
parent_pd = scpsys->pd_data.domains[id];
|
||||
|
||||
child_pd = scpsys_add_one_domain(scpsys, child);
|
||||
if (IS_ERR(child_pd)) {
|
||||
ret = PTR_ERR(child_pd);
|
||||
dev_err(scpsys->dev, "%pOF: failed to get child domain id\n", child);
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
ret = pm_genpd_add_subdomain(parent_pd, child_pd);
|
||||
if (ret) {
|
||||
dev_err(scpsys->dev, "failed to add %s subdomain to parent %s\n",
|
||||
child_pd->name, parent_pd->name);
|
||||
goto err_put_node;
|
||||
} else {
|
||||
dev_dbg(scpsys->dev, "%s add subdomain: %s\n", parent_pd->name,
|
||||
child_pd->name);
|
||||
}
|
||||
|
||||
/* recursive call to add all subdomains */
|
||||
ret = scpsys_add_subdomain(scpsys, child);
|
||||
if (ret)
|
||||
goto err_put_node;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_node:
|
||||
of_node_put(child);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void scpsys_remove_one_domain(struct scpsys_domain *pd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (scpsys_domain_is_on(pd))
|
||||
scpsys_power_off(&pd->genpd);
|
||||
|
||||
/*
|
||||
* We're in the error cleanup already, so we only complain,
|
||||
* but won't emit another error on top of the original one.
|
||||
*/
|
||||
ret = pm_genpd_remove(&pd->genpd);
|
||||
if (ret < 0)
|
||||
dev_err(pd->scpsys->dev,
|
||||
"failed to remove domain '%s' : %d - state may be inconsistent\n",
|
||||
pd->genpd.name, ret);
|
||||
|
||||
clk_bulk_unprepare(pd->num_clks, pd->clks);
|
||||
clk_bulk_put(pd->num_clks, pd->clks);
|
||||
|
||||
clk_bulk_unprepare(pd->num_subsys_clks, pd->subsys_clks);
|
||||
clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks);
|
||||
}
|
||||
|
||||
static void scpsys_domain_cleanup(struct scpsys *scpsys)
|
||||
{
|
||||
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];
|
||||
if (genpd) {
|
||||
pd = to_scpsys_domain(genpd);
|
||||
scpsys_remove_one_domain(pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct of_device_id scpsys_of_match[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt8173-power-controller",
|
||||
.data = &mt8173_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8183-power-controller",
|
||||
.data = &mt8183_scpsys_data,
|
||||
},
|
||||
{
|
||||
.compatible = "mediatek,mt8192-power-controller",
|
||||
.data = &mt8192_scpsys_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int scpsys_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
const struct scpsys_soc_data *soc;
|
||||
struct device_node *node;
|
||||
struct device *parent;
|
||||
struct scpsys *scpsys;
|
||||
int ret;
|
||||
|
||||
soc = of_device_get_match_data(&pdev->dev);
|
||||
if (!soc) {
|
||||
dev_err(&pdev->dev, "no power controller data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scpsys = devm_kzalloc(dev, struct_size(scpsys, domains, soc->num_domains), GFP_KERNEL);
|
||||
if (!scpsys)
|
||||
return -ENOMEM;
|
||||
|
||||
scpsys->dev = dev;
|
||||
scpsys->soc_data = soc;
|
||||
|
||||
scpsys->pd_data.domains = scpsys->domains;
|
||||
scpsys->pd_data.num_domains = soc->num_domains;
|
||||
|
||||
parent = dev->parent;
|
||||
if (!parent) {
|
||||
dev_err(dev, "no parent for syscon devices\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
scpsys->base = syscon_node_to_regmap(parent->of_node);
|
||||
if (IS_ERR(scpsys->base)) {
|
||||
dev_err(dev, "no regmap available\n");
|
||||
return PTR_ERR(scpsys->base);
|
||||
}
|
||||
|
||||
ret = -ENODEV;
|
||||
for_each_available_child_of_node(np, node) {
|
||||
struct generic_pm_domain *domain;
|
||||
|
||||
domain = scpsys_add_one_domain(scpsys, node);
|
||||
if (IS_ERR(domain)) {
|
||||
ret = PTR_ERR(domain);
|
||||
of_node_put(node);
|
||||
goto err_cleanup_domains;
|
||||
}
|
||||
|
||||
ret = scpsys_add_subdomain(scpsys, node);
|
||||
if (ret) {
|
||||
of_node_put(node);
|
||||
goto err_cleanup_domains;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_dbg(dev, "no power domains present\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = of_genpd_add_provider_onecell(np, &scpsys->pd_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add provider: %d\n", ret);
|
||||
goto err_cleanup_domains;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_domains:
|
||||
scpsys_domain_cleanup(scpsys);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver scpsys_pm_domain_driver = {
|
||||
.probe = scpsys_probe,
|
||||
.driver = {
|
||||
.name = "mtk-power-controller",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = scpsys_of_match,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(scpsys_pm_domain_driver);
|
|
@ -0,0 +1,102 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __SOC_MEDIATEK_MTK_PM_DOMAINS_H
|
||||
#define __SOC_MEDIATEK_MTK_PM_DOMAINS_H
|
||||
|
||||
#define MTK_SCPD_ACTIVE_WAKEUP BIT(0)
|
||||
#define MTK_SCPD_FWAIT_SRAM BIT(1)
|
||||
#define MTK_SCPD_SRAM_ISO BIT(2)
|
||||
#define MTK_SCPD_KEEP_DEFAULT_OFF BIT(3)
|
||||
#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
|
||||
|
||||
#define SPM_VDE_PWR_CON 0x0210
|
||||
#define SPM_MFG_PWR_CON 0x0214
|
||||
#define SPM_VEN_PWR_CON 0x0230
|
||||
#define SPM_ISP_PWR_CON 0x0238
|
||||
#define SPM_DIS_PWR_CON 0x023c
|
||||
#define SPM_VEN2_PWR_CON 0x0298
|
||||
#define SPM_AUDIO_PWR_CON 0x029c
|
||||
#define SPM_MFG_2D_PWR_CON 0x02c0
|
||||
#define SPM_MFG_ASYNC_PWR_CON 0x02c4
|
||||
#define SPM_USB_PWR_CON 0x02cc
|
||||
|
||||
#define SPM_PWR_STATUS 0x060c
|
||||
#define SPM_PWR_STATUS_2ND 0x0610
|
||||
|
||||
#define PWR_STATUS_CONN BIT(1)
|
||||
#define PWR_STATUS_DISP BIT(3)
|
||||
#define PWR_STATUS_MFG BIT(4)
|
||||
#define PWR_STATUS_ISP BIT(5)
|
||||
#define PWR_STATUS_VDEC BIT(7)
|
||||
#define PWR_STATUS_VENC_LT BIT(20)
|
||||
#define PWR_STATUS_VENC BIT(21)
|
||||
#define PWR_STATUS_MFG_2D BIT(22)
|
||||
#define PWR_STATUS_MFG_ASYNC BIT(23)
|
||||
#define PWR_STATUS_AUDIO BIT(24)
|
||||
#define PWR_STATUS_USB BIT(25)
|
||||
|
||||
#define SPM_MAX_BUS_PROT_DATA 5
|
||||
|
||||
#define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \
|
||||
.bus_prot_mask = (_mask), \
|
||||
.bus_prot_set = _set, \
|
||||
.bus_prot_clr = _clr, \
|
||||
.bus_prot_sta = _sta, \
|
||||
.bus_prot_reg_update = _update, \
|
||||
.ignore_clr_ack = _ignore, \
|
||||
}
|
||||
|
||||
#define BUS_PROT_WR(_mask, _set, _clr, _sta) \
|
||||
_BUS_PROT(_mask, _set, _clr, _sta, false, false)
|
||||
|
||||
#define BUS_PROT_WR_IGN(_mask, _set, _clr, _sta) \
|
||||
_BUS_PROT(_mask, _set, _clr, _sta, false, true)
|
||||
|
||||
#define BUS_PROT_UPDATE(_mask, _set, _clr, _sta) \
|
||||
_BUS_PROT(_mask, _set, _clr, _sta, true, false)
|
||||
|
||||
#define BUS_PROT_UPDATE_TOPAXI(_mask) \
|
||||
BUS_PROT_UPDATE(_mask, \
|
||||
INFRA_TOPAXI_PROTECTEN, \
|
||||
INFRA_TOPAXI_PROTECTEN_CLR, \
|
||||
INFRA_TOPAXI_PROTECTSTA1)
|
||||
|
||||
struct scpsys_bus_prot_data {
|
||||
u32 bus_prot_mask;
|
||||
u32 bus_prot_set;
|
||||
u32 bus_prot_clr;
|
||||
u32 bus_prot_sta;
|
||||
bool bus_prot_reg_update;
|
||||
bool ignore_clr_ack;
|
||||
};
|
||||
|
||||
#define MAX_SUBSYS_CLKS 10
|
||||
|
||||
/**
|
||||
* struct scpsys_domain_data - scp domain data for power on/off flow
|
||||
* @sta_mask: The mask for 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.
|
||||
* @caps: The flag for active wake-up action.
|
||||
* @bp_infracfg: bus protection for infracfg subsystem
|
||||
* @bp_smi: bus protection for smi subsystem
|
||||
*/
|
||||
struct scpsys_domain_data {
|
||||
u32 sta_mask;
|
||||
int ctl_offs;
|
||||
u32 sram_pdn_bits;
|
||||
u32 sram_pdn_ack_bits;
|
||||
u8 caps;
|
||||
const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
|
||||
const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
|
||||
};
|
||||
|
||||
struct scpsys_soc_data {
|
||||
const struct scpsys_domain_data *domains_data;
|
||||
int num_domains;
|
||||
int pwr_sta_offs;
|
||||
int pwr_sta2nd_offs;
|
||||
};
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
|
|
@ -524,6 +524,7 @@ static void mtk_register_power_domains(struct platform_device *pdev,
|
|||
for (i = 0; i < num; i++) {
|
||||
struct scp_domain *scpd = &scp->domains[i];
|
||||
struct generic_pm_domain *genpd = &scpd->genpd;
|
||||
bool on;
|
||||
|
||||
/*
|
||||
* Initially turn on all domains to make the domains usable
|
||||
|
@ -531,9 +532,9 @@ static void mtk_register_power_domains(struct platform_device *pdev,
|
|||
* software. The unused domains will be switched off during
|
||||
* late_init time.
|
||||
*/
|
||||
genpd->power_on(genpd);
|
||||
on = !WARN_ON(genpd->power_on(genpd) < 0);
|
||||
|
||||
pm_genpd_init(genpd, NULL, false);
|
||||
pm_genpd_init(genpd, NULL, !on);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Weiyi Lu <weiyi.lu@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H
|
||||
#define _DT_BINDINGS_POWER_MT8183_POWER_H
|
||||
|
||||
#define MT8183_POWER_DOMAIN_AUDIO 0
|
||||
#define MT8183_POWER_DOMAIN_CONN 1
|
||||
#define MT8183_POWER_DOMAIN_MFG_ASYNC 2
|
||||
#define MT8183_POWER_DOMAIN_MFG 3
|
||||
#define MT8183_POWER_DOMAIN_MFG_CORE0 4
|
||||
#define MT8183_POWER_DOMAIN_MFG_CORE1 5
|
||||
#define MT8183_POWER_DOMAIN_MFG_2D 6
|
||||
#define MT8183_POWER_DOMAIN_DISP 7
|
||||
#define MT8183_POWER_DOMAIN_CAM 8
|
||||
#define MT8183_POWER_DOMAIN_ISP 9
|
||||
#define MT8183_POWER_DOMAIN_VDEC 10
|
||||
#define MT8183_POWER_DOMAIN_VENC 11
|
||||
#define MT8183_POWER_DOMAIN_VPU_TOP 12
|
||||
#define MT8183_POWER_DOMAIN_VPU_CORE0 13
|
||||
#define MT8183_POWER_DOMAIN_VPU_CORE1 14
|
||||
|
||||
#endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */
|
|
@ -0,0 +1,32 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Weiyi Lu <weiyi.lu@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_POWER_MT8192_POWER_H
|
||||
#define _DT_BINDINGS_POWER_MT8192_POWER_H
|
||||
|
||||
#define MT8192_POWER_DOMAIN_AUDIO 0
|
||||
#define MT8192_POWER_DOMAIN_CONN 1
|
||||
#define MT8192_POWER_DOMAIN_MFG0 2
|
||||
#define MT8192_POWER_DOMAIN_MFG1 3
|
||||
#define MT8192_POWER_DOMAIN_MFG2 4
|
||||
#define MT8192_POWER_DOMAIN_MFG3 5
|
||||
#define MT8192_POWER_DOMAIN_MFG4 6
|
||||
#define MT8192_POWER_DOMAIN_MFG5 7
|
||||
#define MT8192_POWER_DOMAIN_MFG6 8
|
||||
#define MT8192_POWER_DOMAIN_DISP 9
|
||||
#define MT8192_POWER_DOMAIN_IPE 10
|
||||
#define MT8192_POWER_DOMAIN_ISP 11
|
||||
#define MT8192_POWER_DOMAIN_ISP2 12
|
||||
#define MT8192_POWER_DOMAIN_MDP 13
|
||||
#define MT8192_POWER_DOMAIN_VENC 14
|
||||
#define MT8192_POWER_DOMAIN_VDEC 15
|
||||
#define MT8192_POWER_DOMAIN_VDEC2 16
|
||||
#define MT8192_POWER_DOMAIN_CAM 17
|
||||
#define MT8192_POWER_DOMAIN_CAM_RAWA 18
|
||||
#define MT8192_POWER_DOMAIN_CAM_RAWB 19
|
||||
#define MT8192_POWER_DOMAIN_CAM_RAWC 20
|
||||
|
||||
#endif /* _DT_BINDINGS_POWER_MT8192_POWER_H */
|
|
@ -28,6 +28,9 @@ extern struct regmap *syscon_regmap_lookup_by_phandle_args(
|
|||
const char *property,
|
||||
int arg_count,
|
||||
unsigned int *out_args);
|
||||
extern struct regmap *syscon_regmap_lookup_by_phandle_optional(
|
||||
struct device_node *np,
|
||||
const char *property);
|
||||
#else
|
||||
static inline struct regmap *device_node_to_regmap(struct device_node *np)
|
||||
{
|
||||
|
@ -59,6 +62,14 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle_args(
|
|||
{
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct regmap *syscon_regmap_lookup_by_phandle_optional(
|
||||
struct device_node *np,
|
||||
const char *property)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __LINUX_MFD_SYSCON_H__ */
|
||||
|
|
|
@ -2,6 +2,108 @@
|
|||
#ifndef __SOC_MEDIATEK_INFRACFG_H
|
||||
#define __SOC_MEDIATEK_INFRACFG_H
|
||||
|
||||
#define MT8192_TOP_AXI_PROT_EN_STA1 0x228
|
||||
#define MT8192_TOP_AXI_PROT_EN_1_STA1 0x258
|
||||
#define MT8192_TOP_AXI_PROT_EN_SET 0x2a0
|
||||
#define MT8192_TOP_AXI_PROT_EN_CLR 0x2a4
|
||||
#define MT8192_TOP_AXI_PROT_EN_1_SET 0x2a8
|
||||
#define MT8192_TOP_AXI_PROT_EN_1_CLR 0x2ac
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_SET 0x2d4
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_CLR 0x2d8
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_STA1 0x2ec
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_SET 0x714
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_CLR 0x718
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_STA1 0x724
|
||||
#define MT8192_TOP_AXI_PROT_EN_VDNR_SET 0xb84
|
||||
#define MT8192_TOP_AXI_PROT_EN_VDNR_CLR 0xb88
|
||||
#define MT8192_TOP_AXI_PROT_EN_VDNR_STA1 0xb90
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_SET 0xdcc
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_CLR 0xdd0
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_STA1 0xdd8
|
||||
|
||||
#define MT8192_TOP_AXI_PROT_EN_DISP (BIT(6) | BIT(23))
|
||||
#define MT8192_TOP_AXI_PROT_EN_CONN (BIT(13) | BIT(18))
|
||||
#define MT8192_TOP_AXI_PROT_EN_CONN_2ND BIT(14)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MFG1 GENMASK(22, 21)
|
||||
#define MT8192_TOP_AXI_PROT_EN_1_CONN BIT(10)
|
||||
#define MT8192_TOP_AXI_PROT_EN_1_MFG1 BIT(21)
|
||||
#define MT8192_TOP_AXI_PROT_EN_1_CAM BIT(22)
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_CAM BIT(0)
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_ADSP BIT(3)
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_AUDIO BIT(4)
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_MFG1 GENMASK(6, 5)
|
||||
#define MT8192_TOP_AXI_PROT_EN_2_MFG1_2ND BIT(7)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_CAM (BIT(0) | BIT(2))
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_DISP (BIT(0) | BIT(2) | \
|
||||
BIT(10) | BIT(12) | \
|
||||
BIT(14) | BIT(16) | \
|
||||
BIT(24) | BIT(26))
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_CAM_2ND (BIT(1) | BIT(3))
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_DISP_2ND (BIT(1) | BIT(3) | \
|
||||
BIT(15) | BIT(17) | \
|
||||
BIT(25) | BIT(27))
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_ISP2 BIT(14)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_ISP2_2ND BIT(15)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_IPE BIT(16)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_IPE_2ND BIT(17)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_VDEC BIT(24)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_VDEC_2ND BIT(25)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_VENC BIT(26)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_VENC_2ND BIT(27)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_ISP BIT(8)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_DISP (BIT(8) | BIT(12))
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_ISP_2ND BIT(9)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_DISP_2ND (BIT(9) | BIT(13))
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_MDP BIT(12)
|
||||
#define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND BIT(13)
|
||||
#define MT8192_TOP_AXI_PROT_EN_VDNR_CAM BIT(21)
|
||||
|
||||
#define MT8183_TOP_AXI_PROT_EN_STA1 0x228
|
||||
#define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258
|
||||
#define MT8183_TOP_AXI_PROT_EN_SET 0x2a0
|
||||
#define MT8183_TOP_AXI_PROT_EN_CLR 0x2a4
|
||||
#define MT8183_TOP_AXI_PROT_EN_1_SET 0x2a8
|
||||
#define MT8183_TOP_AXI_PROT_EN_1_CLR 0x2ac
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_SET 0x2c4
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_CLR 0x2c8
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_STA1 0x2e4
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_SET 0x2d4
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_CLR 0x2d8
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_STA1 0x2ec
|
||||
|
||||
#define MT8183_TOP_AXI_PROT_EN_DISP (BIT(10) | BIT(11))
|
||||
#define MT8183_TOP_AXI_PROT_EN_CONN (BIT(13) | BIT(14))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MFG (BIT(21) | BIT(22))
|
||||
#define MT8183_TOP_AXI_PROT_EN_CAM BIT(28)
|
||||
#define MT8183_TOP_AXI_PROT_EN_VPU_TOP BIT(27)
|
||||
#define MT8183_TOP_AXI_PROT_EN_1_DISP (BIT(16) | BIT(17))
|
||||
#define MT8183_TOP_AXI_PROT_EN_1_MFG GENMASK(21, 19)
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_ISP (BIT(3) | BIT(8))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND BIT(10)
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_CAM (BIT(4) | BIT(5) | \
|
||||
BIT(9) | BIT(13))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP (GENMASK(9, 6) | \
|
||||
BIT(12))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND (BIT(10) | BIT(11))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND BIT(11)
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND (BIT(0) | BIT(2) | \
|
||||
BIT(4))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND (BIT(1) | BIT(3) | \
|
||||
BIT(5))
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0 BIT(6)
|
||||
#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1 BIT(7)
|
||||
|
||||
#define MT8183_SMI_COMMON_CLAMP_EN 0x3c0
|
||||
#define MT8183_SMI_COMMON_CLAMP_EN_SET 0x3c4
|
||||
#define MT8183_SMI_COMMON_CLAMP_EN_CLR 0x3c8
|
||||
|
||||
#define MT8183_SMI_COMMON_SMI_CLAMP_DISP GENMASK(7, 0)
|
||||
#define MT8183_SMI_COMMON_SMI_CLAMP_VENC BIT(1)
|
||||
#define MT8183_SMI_COMMON_SMI_CLAMP_ISP BIT(2)
|
||||
#define MT8183_SMI_COMMON_SMI_CLAMP_CAM (BIT(3) | BIT(4))
|
||||
#define MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP (BIT(5) | BIT(6))
|
||||
#define MT8183_SMI_COMMON_SMI_CLAMP_VDEC BIT(7)
|
||||
|
||||
#define MT8173_TOP_AXI_PROT_EN_MCI_M2 BIT(0)
|
||||
#define MT8173_TOP_AXI_PROT_EN_MM_M0 BIT(1)
|
||||
#define MT8173_TOP_AXI_PROT_EN_MM_M1 BIT(2)
|
||||
|
@ -32,6 +134,11 @@
|
|||
#define MT7622_TOP_AXI_PROT_EN_WB (BIT(2) | BIT(6) | \
|
||||
BIT(7) | BIT(8))
|
||||
|
||||
#define INFRA_TOPAXI_PROTECTEN 0x0220
|
||||
#define INFRA_TOPAXI_PROTECTSTA1 0x0228
|
||||
#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
|
||||
#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
|
||||
|
||||
#define REG_INFRA_MISC 0xf00
|
||||
#define F_DDR_4GB_SUPPORT_EN BIT(13)
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <linux/mailbox/mtk-cmdq-mailbox.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#define CMDQ_NO_TIMEOUT 0xffffffffu
|
||||
#define CMDQ_ADDR_HIGH(addr) ((u32)(((addr) >> 16) & GENMASK(31, 0)))
|
||||
#define CMDQ_ADDR_LOW(addr) ((u16)(addr) | BIT(1))
|
||||
|
||||
|
@ -24,12 +23,8 @@ struct cmdq_client_reg {
|
|||
};
|
||||
|
||||
struct cmdq_client {
|
||||
spinlock_t lock;
|
||||
u32 pkt_cnt;
|
||||
struct mbox_client client;
|
||||
struct mbox_chan *chan;
|
||||
struct timer_list timer;
|
||||
u32 timeout_ms; /* in unit of microsecond */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -51,13 +46,10 @@ int cmdq_dev_get_client_reg(struct device *dev,
|
|||
* cmdq_mbox_create() - create CMDQ mailbox client and channel
|
||||
* @dev: device of CMDQ mailbox client
|
||||
* @index: index of CMDQ mailbox channel
|
||||
* @timeout: timeout of a pkt execution by GCE, in unit of microsecond, set
|
||||
* CMDQ_NO_TIMEOUT if a timer is not used.
|
||||
*
|
||||
* Return: CMDQ mailbox client pointer
|
||||
*/
|
||||
struct cmdq_client *cmdq_mbox_create(struct device *dev, int index,
|
||||
u32 timeout);
|
||||
struct cmdq_client *cmdq_mbox_create(struct device *dev, int index);
|
||||
|
||||
/**
|
||||
* cmdq_mbox_destroy() - destroy CMDQ mailbox client and channel
|
||||
|
|
|
@ -9,6 +9,39 @@
|
|||
enum mtk_ddp_comp_id;
|
||||
struct device;
|
||||
|
||||
enum mtk_ddp_comp_id {
|
||||
DDP_COMPONENT_AAL0,
|
||||
DDP_COMPONENT_AAL1,
|
||||
DDP_COMPONENT_BLS,
|
||||
DDP_COMPONENT_CCORR,
|
||||
DDP_COMPONENT_COLOR0,
|
||||
DDP_COMPONENT_COLOR1,
|
||||
DDP_COMPONENT_DITHER,
|
||||
DDP_COMPONENT_DPI0,
|
||||
DDP_COMPONENT_DPI1,
|
||||
DDP_COMPONENT_DSI0,
|
||||
DDP_COMPONENT_DSI1,
|
||||
DDP_COMPONENT_DSI2,
|
||||
DDP_COMPONENT_DSI3,
|
||||
DDP_COMPONENT_GAMMA,
|
||||
DDP_COMPONENT_OD0,
|
||||
DDP_COMPONENT_OD1,
|
||||
DDP_COMPONENT_OVL0,
|
||||
DDP_COMPONENT_OVL_2L0,
|
||||
DDP_COMPONENT_OVL_2L1,
|
||||
DDP_COMPONENT_OVL1,
|
||||
DDP_COMPONENT_PWM0,
|
||||
DDP_COMPONENT_PWM1,
|
||||
DDP_COMPONENT_PWM2,
|
||||
DDP_COMPONENT_RDMA0,
|
||||
DDP_COMPONENT_RDMA1,
|
||||
DDP_COMPONENT_RDMA2,
|
||||
DDP_COMPONENT_UFOE,
|
||||
DDP_COMPONENT_WDMA0,
|
||||
DDP_COMPONENT_WDMA1,
|
||||
DDP_COMPONENT_ID_MAX,
|
||||
};
|
||||
|
||||
void mtk_mmsys_ddp_connect(struct device *dev,
|
||||
enum mtk_ddp_comp_id cur,
|
||||
enum mtk_ddp_comp_id next);
|
||||
|
|
Загрузка…
Ссылка в новой задаче