Commit d6d58c35 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'v5.11-next-soc' of...

Merge tag 'v5.11-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux into arm/drivers

pm-domains:
- add support for MT8167
- add support for regulator needed by a PM domain
- make error message in deferred probe case better

cmdq-helper:
- remove arch specific flush function, use mailbox rx_callback instead

* tag 'v5.11-next-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux:
  soc: mediatek: pm-domains: Don't print an error if child domain is deferred
  soc: mediatek: pm-domains: Add domain regulator supply
  dt-bindings: power: Add domain regulator supply
  soc: mediatek: cmdq: Remove cmdq_pkt_flush()
  soc: mediatek: pm-domains: Add support for mt8167
  dt-bindings: power: Add MT8167 power domains

Link: https://lore.kernel.org/r/5faa52c2-0ddb-b809-7444-ce6f6ff6d8ad@gmail.com


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 1d025e0a dd650302
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ properties:

  compatible:
    enum:
      - mediatek,mt8167-power-controller
      - mediatek,mt8173-power-controller
      - mediatek,mt8183-power-controller
      - mediatek,mt8192-power-controller
@@ -59,6 +60,7 @@ patternProperties:
      reg:
        description: |
          Power domain index. Valid values are defined in:
              "include/dt-bindings/power/mt8167-power.h" - for MT8167 type power domain.
              "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.
@@ -82,6 +84,9 @@ patternProperties:
          be specified by order, adding first the BASIC clocks followed by the
          SUSBSYS clocks.

      domain-supply:
        description: domain regulator supply.

      mediatek,infracfg:
        $ref: /schemas/types.yaml#/definitions/phandle
        description: phandle to the device containing the INFRACFG register range.
@@ -130,6 +135,9 @@ patternProperties:
              be specified by order, adding first the BASIC clocks followed by the
              SUSBSYS clocks.

          domain-supply:
            description: domain regulator supply.

          mediatek,infracfg:
            $ref: /schemas/types.yaml#/definitions/phandle
            description: phandle to the device containing the INFRACFG register range.
@@ -178,6 +186,9 @@ patternProperties:
                  be specified by order, adding first the BASIC clocks followed by the
                  SUSBSYS clocks.

              domain-supply:
                description: domain regulator supply.

              mediatek,infracfg:
                $ref: /schemas/types.yaml#/definitions/phandle
                description: phandle to the device containing the INFRACFG register range.
+86 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __SOC_MEDIATEK_MT8167_PM_DOMAINS_H
#define __SOC_MEDIATEK_MT8167_PM_DOMAINS_H

#include "mtk-pm-domains.h"
#include <dt-bindings/power/mt8167-power.h>

#define MT8167_PWR_STATUS_MFG_2D	BIT(24)
#define MT8167_PWR_STATUS_MFG_ASYNC	BIT(25)

/*
 * MT8167 power domain support
 */

static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
	[MT8167_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(MT8167_TOP_AXI_PROT_EN_MM_EMI |
					       MT8167_TOP_AXI_PROT_EN_MCU_MM),
		},
		.caps = MTK_SCPD_ACTIVE_WAKEUP,
	},
	[MT8167_POWER_DOMAIN_VDEC] = {
		.sta_mask = PWR_STATUS_VDEC,
		.ctl_offs = SPM_VDE_PWR_CON,
		.sram_pdn_bits = GENMASK(8, 8),
		.sram_pdn_ack_bits = GENMASK(12, 12),
		.caps = MTK_SCPD_ACTIVE_WAKEUP,
	},
	[MT8167_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),
		.caps = MTK_SCPD_ACTIVE_WAKEUP,
	},
	[MT8167_POWER_DOMAIN_MFG_ASYNC] = {
		.sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,
		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
		.sram_pdn_bits = 0,
		.sram_pdn_ack_bits = 0,
		.bp_infracfg = {
			BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_MCU_MFG |
					       MT8167_TOP_AXI_PROT_EN_MFG_EMI),
		},
	},
	[MT8167_POWER_DOMAIN_MFG_2D] = {
		.sta_mask = MT8167_PWR_STATUS_MFG_2D,
		.ctl_offs = SPM_MFG_2D_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
	},
	[MT8167_POWER_DOMAIN_MFG] = {
		.sta_mask = PWR_STATUS_MFG,
		.ctl_offs = SPM_MFG_PWR_CON,
		.sram_pdn_bits = GENMASK(11, 8),
		.sram_pdn_ack_bits = GENMASK(15, 12),
	},
	[MT8167_POWER_DOMAIN_CONN] = {
		.sta_mask = PWR_STATUS_CONN,
		.ctl_offs = SPM_CONN_PWR_CON,
		.sram_pdn_bits = GENMASK(8, 8),
		.sram_pdn_ack_bits = 0,
		.caps = MTK_SCPD_ACTIVE_WAKEUP,
		.bp_infracfg = {
			BUS_PROT_UPDATE_TOPAXI(MT8167_TOP_AXI_PROT_EN_CONN_EMI |
					       MT8167_TOP_AXI_PROT_EN_CONN_MCU |
					       MT8167_TOP_AXI_PROT_EN_MCU_CONN),
		},
	},
};

static const struct scpsys_soc_data mt8167_scpsys_data = {
	.domains_data = scpsys_domain_data_mt8167,
	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
	.pwr_sta_offs = SPM_PWR_STATUS,
	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
};

#endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */
+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
		.ctl_offs = 0x0338,
		.sram_pdn_bits = GENMASK(8, 8),
		.sram_pdn_ack_bits = GENMASK(12, 12),
		.caps = MTK_SCPD_DOMAIN_SUPPLY,
	},
	[MT8183_POWER_DOMAIN_MFG_CORE0] = {
		.sta_mask = BIT(7),
+0 −32
Original line number Diff line number Diff line
@@ -463,36 +463,4 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
}
EXPORT_SYMBOL(cmdq_pkt_flush_async);

struct cmdq_flush_completion {
	struct completion cmplt;
	bool err;
};

static void cmdq_pkt_flush_cb(struct cmdq_cb_data data)
{
	struct cmdq_flush_completion *cmplt;

	cmplt = (struct cmdq_flush_completion *)data.data;
	if (data.sta != CMDQ_CB_NORMAL)
		cmplt->err = true;
	else
		cmplt->err = false;
	complete(&cmplt->cmplt);
}

int cmdq_pkt_flush(struct cmdq_pkt *pkt)
{
	struct cmdq_flush_completion cmplt;
	int err;

	init_completion(&cmplt.cmplt);
	err = cmdq_pkt_flush_async(pkt, cmdq_pkt_flush_cb, &cmplt);
	if (err < 0)
		return err;
	wait_for_completion(&cmplt.cmplt);

	return cmplt.err ? -EFAULT : 0;
}
EXPORT_SYMBOL(cmdq_pkt_flush);

MODULE_LICENSE("GPL v2");
+48 −3
Original line number Diff line number Diff line
@@ -13,8 +13,10 @@
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/soc/mediatek/infracfg.h>

#include "mt8167-pm-domains.h"
#include "mt8173-pm-domains.h"
#include "mt8183-pm-domains.h"
#include "mt8192-pm-domains.h"
@@ -40,6 +42,7 @@ struct scpsys_domain {
	struct clk_bulk_data *subsys_clks;
	struct regmap *infracfg;
	struct regmap *smi;
	struct regulator *supply;
};

struct scpsys {
@@ -187,6 +190,16 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
	return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg);
}

static int scpsys_regulator_enable(struct regulator *supply)
{
	return supply ? regulator_enable(supply) : 0;
}

static int scpsys_regulator_disable(struct regulator *supply)
{
	return supply ? regulator_disable(supply) : 0;
}

static int scpsys_power_on(struct generic_pm_domain *genpd)
{
	struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
@@ -194,10 +207,14 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
	bool tmp;
	int ret;

	ret = clk_bulk_enable(pd->num_clks, pd->clks);
	ret = scpsys_regulator_enable(pd->supply);
	if (ret)
		return ret;

	ret = clk_bulk_enable(pd->num_clks, pd->clks);
	if (ret)
		goto err_reg;

	/* 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);
@@ -232,6 +249,8 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
	clk_bulk_disable(pd->num_subsys_clks, pd->subsys_clks);
err_pwr_ack:
	clk_bulk_disable(pd->num_clks, pd->clks);
err_reg:
	scpsys_regulator_disable(pd->supply);
	return ret;
}

@@ -267,6 +286,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)

	clk_bulk_disable(pd->num_clks, pd->clks);

	scpsys_regulator_disable(pd->supply);

	return 0;
}

@@ -275,6 +296,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
{
	const struct scpsys_domain_data *domain_data;
	struct scpsys_domain *pd;
	struct device_node *root_node = scpsys->dev->of_node;
	struct property *prop;
	const char *clk_name;
	int i, ret, num_clks;
@@ -307,6 +329,25 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
	pd->data = domain_data;
	pd->scpsys = scpsys;

	if (MTK_SCPD_CAPS(pd, MTK_SCPD_DOMAIN_SUPPLY)) {
		/*
		 * Find regulator in current power domain node.
		 * devm_regulator_get() finds regulator in a node and its child
		 * node, so set of_node to current power domain node then change
		 * back to original node after regulator is found for current
		 * power domain node.
		 */
		scpsys->dev->of_node = node;
		pd->supply = devm_regulator_get(scpsys->dev, "domain");
		scpsys->dev->of_node = root_node;
		if (IS_ERR(pd->supply)) {
			dev_err_probe(scpsys->dev, PTR_ERR(pd->supply),
				      "%pOF: failed to get power supply.\n",
				      node);
			return ERR_CAST(pd->supply);
		}
	}

	pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg");
	if (IS_ERR(pd->infracfg))
		return ERR_CAST(pd->infracfg);
@@ -446,8 +487,8 @@ static int scpsys_add_subdomain(struct scpsys *scpsys, struct device_node *paren

		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);
			dev_err_probe(scpsys->dev, PTR_ERR(child_pd),
				      "%pOF: failed to get child domain id\n", child);
			goto err_put_node;
		}

@@ -514,6 +555,10 @@ static void scpsys_domain_cleanup(struct scpsys *scpsys)
}

static const struct of_device_id scpsys_of_match[] = {
	{
		.compatible = "mediatek,mt8167-power-controller",
		.data = &mt8167_scpsys_data,
	},
	{
		.compatible = "mediatek,mt8173-power-controller",
		.data = &mt8173_scpsys_data,
Loading