Unverified Commit e0530b9e authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

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

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

i.MX drivers change for 6.3:

- A couple of cleanups to drop device_driver owner setting from i.MX93
  PD and SRC driver.
- A series from Lucas Stach to add high performance PLL clock support
  for imx8mp-blk-ctrl driver.
- A couple of changes to set LCDIF panic read hurry level for i.MX8M
  blk-ctrl drivers.
- Use devm_platform_get_and_ioremap_resource() for imx-weim bus driver.

* tag 'imx-drivers-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
  soc: imx: imx8mp-blk-ctrl: set HDMI LCDIF panic read hurry level
  soc: imx: imx93-src: No need to set device_driver owner
  soc: imx: imx93-pd: No need to set device_driver owner
  soc: imx: imx8m-blk-ctrl: set LCDIF panic read hurry level
  soc: imx: imx8mp-blk-ctrl: expose high performance PLL clock
  soc: imx: imx8mp-blk-ctrl: add instance specific probe function
  soc: imx: add Kconfig symbols for blk-ctrl drivers
  bus: imx-weim: use devm_platform_get_and_ioremap_resource()

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


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 938370c6 9ec590a8
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -263,7 +263,6 @@ static int weim_parse_dt(struct platform_device *pdev)
static int weim_probe(struct platform_device *pdev)
{
	struct weim_priv *priv;
	struct resource *res;
	struct clk *clk;
	void __iomem *base;
	int ret;
@@ -273,8 +272,7 @@ static int weim_probe(struct platform_device *pdev)
		return -ENOMEM;

	/* get the resource */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
	base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
	if (IS_ERR(base))
		return PTR_ERR(base);

+11 −0
Original line number Diff line number Diff line
@@ -28,4 +28,15 @@ config SOC_IMX9
	help
	  If you say yes here, you get support for the NXP i.MX9 family

config IMX8M_BLK_CTRL
	bool
	default SOC_IMX8M && IMX_GPCV2_PM_DOMAINS
	depends on PM_GENERIC_DOMAINS
	depends on COMMON_CLK

config IMX9_BLK_CTRL
	bool
	default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS
	depends on PM_GENERIC_DOMAINS

endmenu
+3 −3
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ endif
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o
obj-$(CONFIG_IMX8M_BLK_CTRL) += imx8m-blk-ctrl.o
obj-$(CONFIG_IMX8M_BLK_CTRL) += imx8mp-blk-ctrl.o
obj-$(CONFIG_SOC_IMX9) += imx93-src.o imx93-pd.o
obj-$(CONFIG_SOC_IMX9) += imx93-blk-ctrl.o
obj-$(CONFIG_IMX9_BLK_CTRL) += imx93-blk-ctrl.o
+21 −6
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Copyright 2021 Pengutronix, Lucas Stach <kernel@pengutronix.de>
 */

#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/module.h>
@@ -654,6 +655,10 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
	.num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
};

#define LCDIF_ARCACHE_CTRL	0x4c
#define  LCDIF_1_RD_HURRY	GENMASK(15, 13)
#define  LCDIF_0_RD_HURRY	GENMASK(12, 10)

static int imx8mp_media_power_notifier(struct notifier_block *nb,
				unsigned long action, void *data)
{
@@ -667,14 +672,24 @@ static int imx8mp_media_power_notifier(struct notifier_block *nb,
	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8));
	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8));

	if (action == GENPD_NOTIFY_ON) {
		/*
		 * On power up we have no software backchannel to the GPC to
		 * wait for the ADB handshake to happen, so we just delay for a
		 * bit. On power down the GPC driver waits for the handshake.
		 */
	if (action == GENPD_NOTIFY_ON)
		udelay(5);

		/*
		 * Set panic read hurry level for both LCDIF interfaces to
		 * maximum priority to minimize chances of display FIFO
		 * underflow.
		 */
		regmap_set_bits(bc->regmap, LCDIF_ARCACHE_CTRL,
				FIELD_PREP(LCDIF_1_RD_HURRY, 7) |
				FIELD_PREP(LCDIF_0_RD_HURRY, 7));
	}

	return NOTIFY_OK;
}

+108 −0
Original line number Diff line number Diff line
@@ -4,7 +4,9 @@
 * Copyright 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/module.h>
@@ -21,6 +23,15 @@
#define  USB_CLOCK_MODULE_EN	BIT(1)
#define  PCIE_PHY_APB_RST	BIT(4)
#define  PCIE_PHY_INIT_RST	BIT(5)
#define GPR_REG1		0x4
#define  PLL_LOCK		BIT(13)
#define GPR_REG2		0x8
#define  P_PLL_MASK		GENMASK(5, 0)
#define  M_PLL_MASK		GENMASK(15, 6)
#define  S_PLL_MASK		GENMASK(18, 16)
#define GPR_REG3		0xc
#define  PLL_CKE		BIT(17)
#define  PLL_RST		BIT(31)

struct imx8mp_blk_ctrl_domain;

@@ -60,6 +71,7 @@ struct imx8mp_blk_ctrl_domain {

struct imx8mp_blk_ctrl_data {
	int max_reg;
	int (*probe) (struct imx8mp_blk_ctrl *bc);
	notifier_fn_t power_notifier_fn;
	void (*power_off) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain);
	void (*power_on) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain);
@@ -73,6 +85,92 @@ to_imx8mp_blk_ctrl_domain(struct generic_pm_domain *genpd)
	return container_of(genpd, struct imx8mp_blk_ctrl_domain, genpd);
}

struct clk_hsio_pll {
	struct clk_hw	hw;
	struct regmap *regmap;
};

static inline struct clk_hsio_pll *to_clk_hsio_pll(struct clk_hw *hw)
{
	return container_of(hw, struct clk_hsio_pll, hw);
}

static int clk_hsio_pll_prepare(struct clk_hw *hw)
{
	struct clk_hsio_pll *clk = to_clk_hsio_pll(hw);
	u32 val;

	/* set the PLL configuration */
	regmap_update_bits(clk->regmap, GPR_REG2,
			   P_PLL_MASK | M_PLL_MASK | S_PLL_MASK,
			   FIELD_PREP(P_PLL_MASK, 12) |
			   FIELD_PREP(M_PLL_MASK, 800) |
			   FIELD_PREP(S_PLL_MASK, 4));

	/* de-assert PLL reset */
	regmap_update_bits(clk->regmap, GPR_REG3, PLL_RST, PLL_RST);

	/* enable PLL */
	regmap_update_bits(clk->regmap, GPR_REG3, PLL_CKE, PLL_CKE);

	return regmap_read_poll_timeout(clk->regmap, GPR_REG1, val,
					val & PLL_LOCK, 10, 100);
}

static void clk_hsio_pll_unprepare(struct clk_hw *hw)
{
	struct clk_hsio_pll *clk = to_clk_hsio_pll(hw);

	regmap_update_bits(clk->regmap, GPR_REG3, PLL_RST | PLL_CKE, 0);
}

static int clk_hsio_pll_is_prepared(struct clk_hw *hw)
{
	struct clk_hsio_pll *clk = to_clk_hsio_pll(hw);

	return regmap_test_bits(clk->regmap, GPR_REG1, PLL_LOCK);
}

static unsigned long clk_hsio_pll_recalc_rate(struct clk_hw *hw,
					      unsigned long parent_rate)
{
	return 100000000;
}

static const struct clk_ops clk_hsio_pll_ops = {
	.prepare = clk_hsio_pll_prepare,
	.unprepare = clk_hsio_pll_unprepare,
	.is_prepared = clk_hsio_pll_is_prepared,
	.recalc_rate = clk_hsio_pll_recalc_rate,
};

static int imx8mp_hsio_blk_ctrl_probe(struct imx8mp_blk_ctrl *bc)
{
	struct clk_hsio_pll *clk_hsio_pll;
	struct clk_hw *hw;
	struct clk_init_data init = {};
	int ret;

	clk_hsio_pll = devm_kzalloc(bc->dev, sizeof(*clk_hsio_pll), GFP_KERNEL);
	if (!clk_hsio_pll)
		return -ENOMEM;

	init.name = "hsio_pll";
	init.ops = &clk_hsio_pll_ops;
	init.parent_names = (const char *[]){"osc_24m"};
	init.num_parents = 1;

	clk_hsio_pll->regmap = bc->regmap;
	clk_hsio_pll->hw.init = &init;

	hw = &clk_hsio_pll->hw;
	ret = devm_clk_hw_register(bc->dev, hw);
	if (ret)
		return ret;

	return devm_of_clk_add_hw_provider(bc->dev, of_clk_hw_simple_get, hw);
}

static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
					  struct imx8mp_blk_ctrl_domain *domain)
{
@@ -187,6 +285,7 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {

static const struct imx8mp_blk_ctrl_data imx8mp_hsio_blk_ctl_dev_data = {
	.max_reg = 0x24,
	.probe = imx8mp_hsio_blk_ctrl_probe,
	.power_on = imx8mp_hsio_blk_ctrl_power_on,
	.power_off = imx8mp_hsio_blk_ctrl_power_off,
	.power_notifier_fn = imx8mp_hsio_power_notifier,
@@ -201,6 +300,7 @@ static const struct imx8mp_blk_ctrl_data imx8mp_hsio_blk_ctl_dev_data = {
#define HDMI_RTX_CLK_CTL3	0x70
#define HDMI_RTX_CLK_CTL4	0x80
#define HDMI_TX_CONTROL0	0x200
#define  HDMI_LCDIF_NOC_HURRY_MASK		GENMASK(14, 12)

static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
					  struct imx8mp_blk_ctrl_domain *domain)
@@ -217,6 +317,8 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
		regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11));
		regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0,
				BIT(4) | BIT(5) | BIT(6));
		regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0,
				FIELD_PREP(HDMI_LCDIF_NOC_HURRY_MASK, 7));
		break;
	case IMX8MP_HDMIBLK_PD_PAI:
		regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(17));
@@ -634,6 +736,12 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
		goto cleanup_provider;
	}

	if (bc_data->probe) {
		ret = bc_data->probe(bc);
		if (ret)
			goto cleanup_provider;
	}

	dev_set_drvdata(dev, bc);

	return 0;
Loading