From 9d3975f27e12c89327fbac84c3d8552ecdb72a35 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 16 Dec 2022 21:08:18 +0100 Subject: soc: imx: add Kconfig symbols for blk-ctrl drivers Currently the dependencies of the blk-ctrl drivers are not fully described in Kconfig, which can trip over the compile tests on platforms where those drivers are not usually enabled. Add a non user-selectable symbol to be describe those dependencies. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/Kconfig | 10 ++++++++++ drivers/soc/imx/Makefile | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig index 4b906791d6c7..179bcc896ea2 100644 --- a/drivers/soc/imx/Kconfig +++ b/drivers/soc/imx/Kconfig @@ -28,4 +28,14 @@ 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 + +config IMX9_BLK_CTRL + bool + default SOC_IMX9 && IMX_GPCV2_PM_DOMAINS + depends on PM_GENERIC_DOMAINS + endmenu diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index 7b4099ceafd6..a28c44a1f16a 100644 --- a/drivers/soc/imx/Makefile +++ b/drivers/soc/imx/Makefile @@ -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 -- cgit v1.2.3 From f4b3948e5a90f49b33e89b019d3c641ab9a6fc59 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 16 Dec 2022 21:08:19 +0100 Subject: soc: imx: imx8mp-blk-ctrl: add instance specific probe function Allow the specific blk-ctrl instance to define a function, which will be called during probe to provide device specific extensions. Signed-off-by: Lucas Stach Tested-by: Marcel Ziswiler Tested-by: Lukas F. Hartmann Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8mp-blk-ctrl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 0e3b6ba22f94..b3d9f6e083ba 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -60,6 +60,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); @@ -634,6 +635,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; -- cgit v1.2.3 From 2cbee26e5d592da942a995ddee78ea3eb97ad2fa Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 16 Dec 2022 21:08:20 +0100 Subject: soc: imx: imx8mp-blk-ctrl: expose high performance PLL clock Expose the high performance PLL as a regular Linux clock, so the PCIe PHY can use it when there is no external refclock provided. Signed-off-by: Lucas Stach Tested-by: Marcel Ziswiler Tested-by: Lukas F. Hartmann Signed-off-by: Shawn Guo --- drivers/soc/imx/Kconfig | 1 + drivers/soc/imx/imx8mp-blk-ctrl.c | 98 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig index 179bcc896ea2..a8742fc58f01 100644 --- a/drivers/soc/imx/Kconfig +++ b/drivers/soc/imx/Kconfig @@ -32,6 +32,7 @@ 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 diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index b3d9f6e083ba..0629f64ef4f1 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -4,7 +4,9 @@ * Copyright 2022 Pengutronix, Lucas Stach */ +#include #include +#include #include #include #include @@ -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; @@ -74,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) { @@ -188,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, -- cgit v1.2.3 From 06a9a229b1592abeb10728c8564492f0729f4b83 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Tue, 20 Dec 2022 18:53:53 +0100 Subject: soc: imx: imx8m-blk-ctrl: set LCDIF panic read hurry level When the LCDIF block signals a panic condition due to the display FIFO falling below the threshold, the priority at the NoC level is boosted to the value set in the LCDIF_ARCACHE_CTRL register of i.MX8MP mediamix blk-ctrl. Same as all other blk-ctrl registers this register is reset when the domain is powered down. Initialize the panic hurry levels for both LCIF interfaces to the maximium priority (same as downstream TF-A and proven to work with the other priorities set in the interconnect driver) when coming back from power down. Signed-off-by: Lucas Stach Reviewed-by: Marco Felsch Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8m-blk-ctrl.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c index ddcf6be3d8b4..399cb85105a1 100644 --- a/drivers/soc/imx/imx8m-blk-ctrl.c +++ b/drivers/soc/imx/imx8m-blk-ctrl.c @@ -4,6 +4,7 @@ * Copyright 2021 Pengutronix, Lucas Stach */ +#include #include #include #include @@ -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)); - /* - * 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) + 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. + */ 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; } -- cgit v1.2.3 From 083dab5e69f3dc9a3c85b2d690ff91cfed57e926 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 22 Dec 2022 23:23:16 +0530 Subject: soc: imx: imx93-pd: No need to set device_driver owner There is no need to exclusively set the .owner member of the struct device_driver when defining the platform_driver struct. The Linux core takes care of setting the .owner member as part of the call to module_platform_driver() helper function. Issue identified using the platform_no_drv_owner.cocci Coccinelle semantic patch. Signed-off-by: Deepak R Varma Signed-off-by: Shawn Guo --- drivers/soc/imx/imx93-pd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/imx93-pd.c b/drivers/soc/imx/imx93-pd.c index 4d235c8c4924..832deeed8fd6 100644 --- a/drivers/soc/imx/imx93-pd.c +++ b/drivers/soc/imx/imx93-pd.c @@ -164,7 +164,6 @@ MODULE_DEVICE_TABLE(of, imx93_pd_ids); static struct platform_driver imx93_power_domain_driver = { .driver = { .name = "imx93_power_domain", - .owner = THIS_MODULE, .of_match_table = imx93_pd_ids, }, .probe = imx93_pd_probe, -- cgit v1.2.3 From 3c047887243c72e7835a17e90361ed19e8354bf5 Mon Sep 17 00:00:00 2001 From: Deepak R Varma Date: Thu, 22 Dec 2022 23:27:03 +0530 Subject: soc: imx: imx93-src: No need to set device_driver owner There is no need to exclusively set the .owner member of the struct device_driver when defining the platform_driver struct. The Linux core takes care of setting the .owner member as part of the call to module_platform_driver() helper function. Issue identified using the platform_no_drv_owner.cocci Coccinelle semantic patch. Signed-off-by: Deepak R Varma Signed-off-by: Shawn Guo --- drivers/soc/imx/imx93-src.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/imx93-src.c b/drivers/soc/imx/imx93-src.c index 4d74921cae0f..f1c2e22d5cbd 100644 --- a/drivers/soc/imx/imx93-src.c +++ b/drivers/soc/imx/imx93-src.c @@ -21,7 +21,6 @@ MODULE_DEVICE_TABLE(of, imx93_src_ids); static struct platform_driver imx93_src_driver = { .driver = { .name = "imx93_src", - .owner = THIS_MODULE, .of_match_table = imx93_src_ids, }, .probe = imx93_src_probe, -- cgit v1.2.3 From 9ec590a8a1bbf6610f72124ad79231f2c5875fc9 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 9 Jan 2023 17:12:42 +0100 Subject: soc: imx: imx8mp-blk-ctrl: set HDMI LCDIF panic read hurry level Same as done for both LCDIF interfaces in the MEDIA domain, set the panic priority of the LCDIF instance in the HDMI domain to the maximium NoC priority of 7 to minimize chances of display underflows. Signed-off-by: Lucas Stach Reviewed-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8mp-blk-ctrl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 0629f64ef4f1..28458ed1793b 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -300,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) @@ -316,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)); -- cgit v1.2.3