Commit 62c93360 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'imx-drivers-5.13' of...

Merge tag 'imx-drivers-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers

i.MX drivers change for 5.13:

- Update SCU power domain driver to keep console domain power on.
- Add missing ADC1 power domain to SCU power domain driver.
- Update comments for single global power domain in SCU power domain
  driver.
- Add i.MX51/i.MX53 unique id support to i.MX SoC driver.

* tag 'imx-drivers-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
  firmware: imx: scu-pd: add missed ADC1 pd
  firmware: imx: scu-pd: Update comments for single global power domain
  firmware: imx: scu-pd: do not power off console domain
  soc: imx: add i.MX51/i.MX53 unique id support

Link: https://lore.kernel.org/r/20210331041019.31345-1-shawnguo@kernel.org


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents e9396d6b f63af5f3
Loading
Loading
Loading
Loading
+37 −4
Original line number Diff line number Diff line
@@ -29,6 +29,10 @@
 *    The framework needs some proper extension to support multi power
 *    domain cases.
 *
 *    Update: Genpd assigns the ->of_node for the virtual device before it
 *    invokes ->attach_dev() callback, hence parsing for device resources via
 *    DT should work fine.
 *
 * 2. It also breaks most of current drivers as the driver probe sequence
 *    behavior changed if removing ->power_on|off() callback and use
 *    ->start() and ->stop() instead. genpd_dev_pm_attach will only power
@@ -39,8 +43,11 @@
 *    domain enabled will trigger a HW access error. That means we need fix
 *    most drivers probe sequence with proper runtime pm.
 *
 * In summary, we need fix above two issue before being able to switch to
 * the "single global power domain" way.
 *    Update: Runtime PM support isn't necessary. Instead, this can easily be
 *    fixed in drivers by adding a call to dev_pm_domain_start() during probe.
 *
 * In summary, the second part needs to be addressed via minor updates to the
 * relevant drivers, before the "single global power domain" model can be used.
 *
 */

@@ -86,6 +93,8 @@ struct imx_sc_pd_soc {
	u8 num_ranges;
};

static int imx_con_rsrc;

static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
	/* LSIO SS */
	{ "pwm", IMX_SC_R_PWM_0, 8, true, 0 },
@@ -134,7 +143,7 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
	{ "can", IMX_SC_R_CAN_0, 3, true, 0 },
	{ "ftm", IMX_SC_R_FTM_0, 2, true, 0 },
	{ "lpi2c", IMX_SC_R_I2C_0, 4, true, 0 },
	{ "adc", IMX_SC_R_ADC_0, 1, true, 0 },
	{ "adc", IMX_SC_R_ADC_0, 2, true, 0 },
	{ "lcd", IMX_SC_R_LCD_0, 1, true, 0 },
	{ "lcd0-pwm", IMX_SC_R_LCD_0_PWM_0, 1, true, 0 },
	{ "lpuart", IMX_SC_R_UART_0, 4, true, 0 },
@@ -207,6 +216,23 @@ to_imx_sc_pd(struct generic_pm_domain *genpd)
	return container_of(genpd, struct imx_sc_pm_domain, pd);
}

static void imx_sc_pd_get_console_rsrc(void)
{
	struct of_phandle_args specs;
	int ret;

	if (!of_stdout)
		return;

	ret = of_parse_phandle_with_args(of_stdout, "power-domains",
					 "#power-domain-cells",
					 0, &specs);
	if (ret)
		return;

	imx_con_rsrc = specs.args[0];
}

static int imx_sc_pd_power(struct generic_pm_domain *domain, bool power_on)
{
	struct imx_sc_msg_req_set_resource_power_mode msg;
@@ -267,6 +293,7 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
		      const struct imx_sc_pd_range *pd_ranges)
{
	struct imx_sc_pm_domain *sc_pd;
	bool is_off = true;
	int ret;

	if (!imx_sc_rm_is_resource_owned(pm_ipc_handle, pd_ranges->rsrc + idx))
@@ -288,6 +315,10 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
			 "%s", pd_ranges->name);

	sc_pd->pd.name = sc_pd->name;
	if (imx_con_rsrc == sc_pd->rsrc) {
		sc_pd->pd.flags = GENPD_FLAG_RPM_ALWAYS_ON;
		is_off = false;
	}

	if (sc_pd->rsrc >= IMX_SC_R_LAST) {
		dev_warn(dev, "invalid pd %s rsrc id %d found",
@@ -297,7 +328,7 @@ imx_scu_add_pm_domain(struct device *dev, int idx,
		return NULL;
	}

	ret = pm_genpd_init(&sc_pd->pd, NULL, true);
	ret = pm_genpd_init(&sc_pd->pd, NULL, is_off);
	if (ret) {
		dev_warn(dev, "failed to init pd %s rsrc id %d",
			 sc_pd->name, sc_pd->rsrc);
@@ -363,6 +394,8 @@ static int imx_sc_pd_probe(struct platform_device *pdev)
	if (!pd_soc)
		return -ENODEV;

	imx_sc_pd_get_console_rsrc();

	return imx_scu_init_pm_domains(&pdev->dev, pd_soc);
}

+12 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@
#include <soc/imx/cpu.h>
#include <soc/imx/revision.h>

#define IIM_UID		0x820

#define OCOTP_UID_H	0x420
#define OCOTP_UID_L	0x410

@@ -32,6 +34,7 @@ static int __init imx_soc_device_init(void)
	u64 soc_uid = 0;
	u32 val;
	int ret;
	int i;

	if (of_machine_is_compatible("fsl,ls1021a"))
		return 0;
@@ -68,9 +71,11 @@ static int __init imx_soc_device_init(void)
		soc_id = "i.MX35";
		break;
	case MXC_CPU_MX51:
		ocotp_compat = "fsl,imx51-iim";
		soc_id = "i.MX51";
		break;
	case MXC_CPU_MX53:
		ocotp_compat = "fsl,imx53-iim";
		soc_id = "i.MX53";
		break;
	case MXC_CPU_IMX6SL:
@@ -153,6 +158,13 @@ static int __init imx_soc_device_init(void)
			regmap_read(ocotp, OCOTP_ULP_UID_1, &val);
			soc_uid <<= 16;
			soc_uid |= val & 0xffff;
		} else if (__mxc_cpu_type == MXC_CPU_MX51 ||
			   __mxc_cpu_type == MXC_CPU_MX53) {
			for (i=0; i < 8; i++) {
				regmap_read(ocotp, IIM_UID + i*4, &val);
				soc_uid <<= 8;
				soc_uid |= (val & 0xff);
			}
		} else {
			regmap_read(ocotp, OCOTP_UID_H, &val);
			soc_uid = val;