123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
- From 1892fcf687116720d07135c83d489a23ec56a166 Mon Sep 17 00:00:00 2001
- From: James Liao <jamesjj.liao@mediatek.com>
- Date: Wed, 30 Dec 2015 14:41:43 +0800
- Subject: [PATCH 002/102] soc: mediatek: Separate scpsys driver common code
- Separate scpsys driver common code to mtk-scpsys.c, and move MT8173
- platform code to mtk-scpsys-mt8173.c.
- Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
- ---
- drivers/soc/mediatek/Kconfig | 13 +-
- drivers/soc/mediatek/Makefile | 1 +
- drivers/soc/mediatek/mtk-scpsys-mt8173.c | 179 ++++++++++++++++++
- drivers/soc/mediatek/mtk-scpsys.c | 301 ++++++++----------------------
- drivers/soc/mediatek/mtk-scpsys.h | 54 ++++++
- 5 files changed, 320 insertions(+), 228 deletions(-)
- create mode 100644 drivers/soc/mediatek/mtk-scpsys-mt8173.c
- create mode 100644 drivers/soc/mediatek/mtk-scpsys.h
- --- a/drivers/soc/mediatek/Kconfig
- +++ b/drivers/soc/mediatek/Kconfig
- @@ -22,11 +22,20 @@ config MTK_PMIC_WRAP
-
- config MTK_SCPSYS
- bool "MediaTek SCPSYS Support"
- - depends on ARCH_MEDIATEK || COMPILE_TEST
- - default ARM64 && ARCH_MEDIATEK
- select REGMAP
- select MTK_INFRACFG
- select PM_GENERIC_DOMAINS if PM
- help
- Say yes here to add support for the MediaTek SCPSYS power domain
- driver.
- +
- +config MTK_SCPSYS_MT8173
- + bool "MediaTek MT8173 SCPSYS Support"
- + depends on ARCH_MEDIATEK || COMPILE_TEST
- + select MTK_SCPSYS
- + default ARCH_MEDIATEK
- + help
- + Say yes here to add support for the MT8173 SCPSYS power domain
- + driver.
- + The System Control Processor System (SCPSYS) has several power
- + management related tasks in the system.
- --- a/drivers/soc/mediatek/Makefile
- +++ b/drivers/soc/mediatek/Makefile
- @@ -1,3 +1,4 @@
- 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_MT8173) += mtk-scpsys-mt8173.o
- --- /dev/null
- +++ b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
- @@ -0,0 +1,179 @@
- +/*
- + * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
- + *
- + * This program is free software; you can redistribute it and/or modify
- + * it under the terms of the GNU General Public License version 2 as
- + * published by the Free Software Foundation.
- + *
- + * This program is distributed in the hope that it will be useful,
- + * but WITHOUT ANY WARRANTY; without even the implied warranty of
- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + * GNU General Public License for more details.
- + */
- +#include <linux/mfd/syscon.h>
- +#include <linux/module.h>
- +#include <linux/of_device.h>
- +#include <linux/pm_domain.h>
- +#include <linux/soc/mediatek/infracfg.h>
- +#include <dt-bindings/power/mt8173-power.h>
- +
- +#include "mtk-scpsys.h"
- +
- +#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 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)
- +
- +static const struct scp_domain_data scp_domain_data[] __initconst = {
- + [MT8173_POWER_DOMAIN_VDEC] = {
- + .name = "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),
- + .clk_id = {CLK_MM},
- + },
- + [MT8173_POWER_DOMAIN_VENC] = {
- + .name = "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),
- + .clk_id = {CLK_MM, CLK_VENC},
- + },
- + [MT8173_POWER_DOMAIN_ISP] = {
- + .name = "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),
- + .clk_id = {CLK_MM},
- + },
- + [MT8173_POWER_DOMAIN_MM] = {
- + .name = "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),
- + .clk_id = {CLK_MM},
- + .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
- + MT8173_TOP_AXI_PROT_EN_MM_M1,
- + },
- + [MT8173_POWER_DOMAIN_VENC_LT] = {
- + .name = "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),
- + .clk_id = {CLK_MM, CLK_VENC_LT},
- + },
- + [MT8173_POWER_DOMAIN_AUDIO] = {
- + .name = "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),
- + .clk_id = {CLK_NONE},
- + },
- + [MT8173_POWER_DOMAIN_USB] = {
- + .name = "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),
- + .clk_id = {CLK_NONE},
- + .active_wakeup = true,
- + },
- + [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
- + .name = "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,
- + .clk_id = {CLK_MFG},
- + },
- + [MT8173_POWER_DOMAIN_MFG_2D] = {
- + .name = "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),
- + .clk_id = {CLK_NONE},
- + },
- + [MT8173_POWER_DOMAIN_MFG] = {
- + .name = "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),
- + .clk_id = {CLK_NONE},
- + .bus_prot_mask = 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,
- + },
- +};
- +
- +#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
- +
- +static int __init scpsys_probe(struct platform_device *pdev)
- +{
- + struct scp *scp;
- + struct genpd_onecell_data *pd_data;
- + int ret;
- +
- + scp = init_scp(pdev, scp_domain_data, NUM_DOMAINS);
- + if (IS_ERR(scp))
- + return PTR_ERR(scp);
- +
- + mtk_register_power_domains(pdev, scp, NUM_DOMAINS);
- +
- + pd_data = &scp->pd_data;
- +
- + ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
- + pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
- + if (ret && IS_ENABLED(CONFIG_PM))
- + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
- +
- + ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
- + pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
- + if (ret && IS_ENABLED(CONFIG_PM))
- + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
- +
- + return 0;
- +}
- +
- +static const struct of_device_id of_scpsys_match_tbl[] = {
- + {
- + .compatible = "mediatek,mt8173-scpsys",
- + }, {
- + /* sentinel */
- + }
- +};
- +
- +static struct platform_driver scpsys_drv = {
- + .driver = {
- + .name = "mtk-scpsys-mt8173",
- + .owner = THIS_MODULE,
- + .of_match_table = of_match_ptr(of_scpsys_match_tbl),
- + },
- +};
- +
- +module_platform_driver_probe(scpsys_drv, scpsys_probe);
- --- a/drivers/soc/mediatek/mtk-scpsys.c
- +++ b/drivers/soc/mediatek/mtk-scpsys.c
- @@ -11,28 +11,14 @@
- * GNU General Public License for more details.
- */
- #include <linux/clk.h>
- -#include <linux/delay.h>
- #include <linux/io.h>
- -#include <linux/kernel.h>
- #include <linux/mfd/syscon.h>
- -#include <linux/module.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 <dt-bindings/power/mt8173-power.h>
-
- -#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
- +#include "mtk-scpsys.h"
- +
- #define SPM_PWR_STATUS 0x060c
- #define SPM_PWR_STATUS_2ND 0x0610
-
- @@ -42,153 +28,6 @@
- #define PWR_ON_2ND_BIT BIT(3)
- #define PWR_CLK_DIS_BIT BIT(4)
-
- -#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)
- -
- -enum clk_id {
- - MT8173_CLK_NONE,
- - MT8173_CLK_MM,
- - MT8173_CLK_MFG,
- - MT8173_CLK_VENC,
- - MT8173_CLK_VENC_LT,
- - MT8173_CLK_MAX,
- -};
- -
- -#define MAX_CLKS 2
- -
- -struct scp_domain_data {
- - const char *name;
- - u32 sta_mask;
- - int ctl_offs;
- - u32 sram_pdn_bits;
- - u32 sram_pdn_ack_bits;
- - u32 bus_prot_mask;
- - enum clk_id clk_id[MAX_CLKS];
- - bool active_wakeup;
- -};
- -
- -static const struct scp_domain_data scp_domain_data[] __initconst = {
- - [MT8173_POWER_DOMAIN_VDEC] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_MM},
- - },
- - [MT8173_POWER_DOMAIN_VENC] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
- - },
- - [MT8173_POWER_DOMAIN_ISP] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_MM},
- - },
- - [MT8173_POWER_DOMAIN_MM] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_MM},
- - .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
- - MT8173_TOP_AXI_PROT_EN_MM_M1,
- - },
- - [MT8173_POWER_DOMAIN_VENC_LT] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
- - },
- - [MT8173_POWER_DOMAIN_AUDIO] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_NONE},
- - },
- - [MT8173_POWER_DOMAIN_USB] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_NONE},
- - .active_wakeup = true,
- - },
- - [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
- - .name = "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,
- - .clk_id = {MT8173_CLK_MFG},
- - },
- - [MT8173_POWER_DOMAIN_MFG_2D] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_NONE},
- - },
- - [MT8173_POWER_DOMAIN_MFG] = {
- - .name = "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),
- - .clk_id = {MT8173_CLK_NONE},
- - .bus_prot_mask = 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,
- - },
- -};
- -
- -#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
- -
- -struct scp;
- -
- -struct scp_domain {
- - struct generic_pm_domain genpd;
- - struct scp *scp;
- - struct clk *clk[MAX_CLKS];
- - u32 sta_mask;
- - void __iomem *ctl_addr;
- - u32 sram_pdn_bits;
- - u32 sram_pdn_ack_bits;
- - u32 bus_prot_mask;
- - bool active_wakeup;
- -};
- -
- -struct scp {
- - struct scp_domain domains[NUM_DOMAINS];
- - struct genpd_onecell_data pd_data;
- - struct device *dev;
- - void __iomem *base;
- - struct regmap *infracfg;
- -};
- -
- static int scpsys_domain_is_on(struct scp_domain *scpd)
- {
- struct scp *scp = scpd->scp;
- @@ -398,63 +237,89 @@ static bool scpsys_active_wakeup(struct
- return scpd->active_wakeup;
- }
-
- -static int __init scpsys_probe(struct platform_device *pdev)
- +static void init_clks(struct platform_device *pdev, struct clk *clk[CLK_MAX])
- +{
- + enum clk_id clk_ids[] = {
- + CLK_MM,
- + CLK_MFG,
- + CLK_VENC,
- + CLK_VENC_LT
- + };
- +
- + static const char * const clk_names[] = {
- + "mm",
- + "mfg",
- + "venc",
- + "venc_lt",
- + };
- +
- + int i;
- +
- + for (i = 0; i < ARRAY_SIZE(clk_ids); i++)
- + clk[clk_ids[i]] = devm_clk_get(&pdev->dev, clk_names[i]);
- +}
- +
- +struct scp *init_scp(struct platform_device *pdev,
- + const struct scp_domain_data *scp_domain_data, int num)
- {
- struct genpd_onecell_data *pd_data;
- struct resource *res;
- - int i, j, ret;
- + int i, j;
- struct scp *scp;
- - struct clk *clk[MT8173_CLK_MAX];
- + struct clk *clk[CLK_MAX];
-
- scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
- if (!scp)
- - return -ENOMEM;
- + return ERR_PTR(-ENOMEM);
-
- scp->dev = &pdev->dev;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- scp->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(scp->base))
- - return PTR_ERR(scp->base);
- -
- - pd_data = &scp->pd_data;
- -
- - pd_data->domains = devm_kzalloc(&pdev->dev,
- - sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
- - if (!pd_data->domains)
- - return -ENOMEM;
- -
- - clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
- - if (IS_ERR(clk[MT8173_CLK_MM]))
- - return PTR_ERR(clk[MT8173_CLK_MM]);
- -
- - clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
- - if (IS_ERR(clk[MT8173_CLK_MFG]))
- - return PTR_ERR(clk[MT8173_CLK_MFG]);
- -
- - clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
- - if (IS_ERR(clk[MT8173_CLK_VENC]))
- - return PTR_ERR(clk[MT8173_CLK_VENC]);
- -
- - clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
- - if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
- - return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
- + return ERR_CAST(scp->base);
-
- scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
- "infracfg");
- if (IS_ERR(scp->infracfg)) {
- dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
- PTR_ERR(scp->infracfg));
- - return PTR_ERR(scp->infracfg);
- + return ERR_CAST(scp->infracfg);
- }
-
- - pd_data->num_domains = NUM_DOMAINS;
- + scp->domains = devm_kzalloc(&pdev->dev,
- + sizeof(*scp->domains) * num, GFP_KERNEL);
- + if (!scp->domains)
- + return ERR_PTR(-ENOMEM);
- +
- + pd_data = &scp->pd_data;
-
- - for (i = 0; i < NUM_DOMAINS; i++) {
- + pd_data->domains = devm_kzalloc(&pdev->dev,
- + sizeof(*pd_data->domains) * num, GFP_KERNEL);
- + if (!pd_data->domains)
- + return ERR_PTR(-ENOMEM);
- +
- + pd_data->num_domains = num;
- +
- + init_clks(pdev, clk);
- +
- + for (i = 0; i < num; i++) {
- struct scp_domain *scpd = &scp->domains[i];
- struct generic_pm_domain *genpd = &scpd->genpd;
- const struct scp_domain_data *data = &scp_domain_data[i];
-
- + for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
- + struct clk *c = clk[data->clk_id[j]];
- +
- + if (IS_ERR(c)) {
- + dev_err(&pdev->dev, "%s: clk unavailable\n",
- + data->name);
- + return ERR_CAST(c);
- + }
- +
- + scpd->clk[j] = c;
- + }
- +
- pd_data->domains[i] = genpd;
- scpd->scp = scp;
-
- @@ -464,13 +329,25 @@ static int __init scpsys_probe(struct pl
- scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
- scpd->bus_prot_mask = data->bus_prot_mask;
- scpd->active_wakeup = data->active_wakeup;
- - for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
- - scpd->clk[j] = clk[data->clk_id[j]];
-
- genpd->name = data->name;
- genpd->power_off = scpsys_power_off;
- genpd->power_on = scpsys_power_on;
- genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
- + }
- +
- + return scp;
- +}
- +
- +void mtk_register_power_domains(struct platform_device *pdev,
- + struct scp *scp, int num)
- +{
- + struct genpd_onecell_data *pd_data;
- + int i, ret;
- +
- + for (i = 0; i < num; i++) {
- + struct scp_domain *scpd = &scp->domains[i];
- + struct generic_pm_domain *genpd = &scpd->genpd;
-
- /*
- * Initially turn on all domains to make the domains usable
- @@ -489,37 +366,9 @@ static int __init scpsys_probe(struct pl
- * valid.
- */
-
- - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
- - pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
- - if (ret && IS_ENABLED(CONFIG_PM))
- - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
- -
- - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
- - pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
- - if (ret && IS_ENABLED(CONFIG_PM))
- - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
- + pd_data = &scp->pd_data;
-
- ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
- if (ret)
- dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
- -
- - return 0;
- }
- -
- -static const struct of_device_id of_scpsys_match_tbl[] = {
- - {
- - .compatible = "mediatek,mt8173-scpsys",
- - }, {
- - /* sentinel */
- - }
- -};
- -
- -static struct platform_driver scpsys_drv = {
- - .driver = {
- - .name = "mtk-scpsys",
- - .owner = THIS_MODULE,
- - .of_match_table = of_match_ptr(of_scpsys_match_tbl),
- - },
- -};
- -
- -module_platform_driver_probe(scpsys_drv, scpsys_probe);
- --- /dev/null
- +++ b/drivers/soc/mediatek/mtk-scpsys.h
- @@ -0,0 +1,54 @@
- +#ifndef __DRV_SOC_MTK_H
- +#define __DRV_SOC_MTK_H
- +
- +enum clk_id {
- + CLK_NONE,
- + CLK_MM,
- + CLK_MFG,
- + CLK_VENC,
- + CLK_VENC_LT,
- + CLK_MAX,
- +};
- +
- +#define MAX_CLKS 2
- +
- +struct scp_domain_data {
- + const char *name;
- + u32 sta_mask;
- + int ctl_offs;
- + u32 sram_pdn_bits;
- + u32 sram_pdn_ack_bits;
- + u32 bus_prot_mask;
- + enum clk_id clk_id[MAX_CLKS];
- + bool active_wakeup;
- +};
- +
- +struct scp;
- +
- +struct scp_domain {
- + struct generic_pm_domain genpd;
- + struct scp *scp;
- + struct clk *clk[MAX_CLKS];
- + u32 sta_mask;
- + void __iomem *ctl_addr;
- + u32 sram_pdn_bits;
- + u32 sram_pdn_ack_bits;
- + u32 bus_prot_mask;
- + bool active_wakeup;
- +};
- +
- +struct scp {
- + struct scp_domain *domains;
- + struct genpd_onecell_data pd_data;
- + struct device *dev;
- + void __iomem *base;
- + struct regmap *infracfg;
- +};
- +
- +struct scp *init_scp(struct platform_device *pdev,
- + const struct scp_domain_data *scp_domain_data, int num);
- +
- +void mtk_register_power_domains(struct platform_device *pdev,
- + struct scp *scp, int num);
- +
- +#endif /* __DRV_SOC_MTK_H */
|