Commit e0530b9e authored by Arnd Bergmann's avatar Arnd Bergmann

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.orgSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 938370c6 9ec590a8
...@@ -263,7 +263,6 @@ static int weim_parse_dt(struct platform_device *pdev) ...@@ -263,7 +263,6 @@ static int weim_parse_dt(struct platform_device *pdev)
static int weim_probe(struct platform_device *pdev) static int weim_probe(struct platform_device *pdev)
{ {
struct weim_priv *priv; struct weim_priv *priv;
struct resource *res;
struct clk *clk; struct clk *clk;
void __iomem *base; void __iomem *base;
int ret; int ret;
...@@ -273,8 +272,7 @@ static int weim_probe(struct platform_device *pdev) ...@@ -273,8 +272,7 @@ static int weim_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
/* get the resource */ /* get the resource */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
......
...@@ -28,4 +28,15 @@ config SOC_IMX9 ...@@ -28,4 +28,15 @@ config SOC_IMX9
help help
If you say yes here, you get support for the NXP i.MX9 family 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 endmenu
...@@ -5,7 +5,7 @@ endif ...@@ -5,7 +5,7 @@ endif
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o obj-$(CONFIG_IMX8M_BLK_CTRL) += imx8m-blk-ctrl.o
obj-$(CONFIG_SOC_IMX8M) += imx8mp-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-src.o imx93-pd.o
obj-$(CONFIG_SOC_IMX9) += imx93-blk-ctrl.o obj-$(CONFIG_IMX9_BLK_CTRL) += imx93-blk-ctrl.o
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* Copyright 2021 Pengutronix, Lucas Stach <kernel@pengutronix.de> * Copyright 2021 Pengutronix, Lucas Stach <kernel@pengutronix.de>
*/ */
#include <linux/bitfield.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/interconnect.h> #include <linux/interconnect.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -654,6 +655,10 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = { ...@@ -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), .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, static int imx8mp_media_power_notifier(struct notifier_block *nb,
unsigned long action, void *data) unsigned long action, void *data)
{ {
...@@ -667,14 +672,24 @@ static int imx8mp_media_power_notifier(struct notifier_block *nb, ...@@ -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_CLK_EN, BIT(8));
regmap_set_bits(bc->regmap, BLK_SFT_RSTN, 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 * 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 * wait for the ADB handshake to happen, so we just delay for a
* bit. On power down the GPC driver waits for the handshake. * bit. On power down the GPC driver waits for the handshake.
*/ */
if (action == GENPD_NOTIFY_ON)
udelay(5); 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; return NOTIFY_OK;
} }
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
* Copyright 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de> * Copyright 2022 Pengutronix, Lucas Stach <kernel@pengutronix.de>
*/ */
#include <linux/bitfield.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/interconnect.h> #include <linux/interconnect.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -21,6 +23,15 @@ ...@@ -21,6 +23,15 @@
#define USB_CLOCK_MODULE_EN BIT(1) #define USB_CLOCK_MODULE_EN BIT(1)
#define PCIE_PHY_APB_RST BIT(4) #define PCIE_PHY_APB_RST BIT(4)
#define PCIE_PHY_INIT_RST BIT(5) #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; struct imx8mp_blk_ctrl_domain;
...@@ -60,6 +71,7 @@ struct imx8mp_blk_ctrl_domain { ...@@ -60,6 +71,7 @@ struct imx8mp_blk_ctrl_domain {
struct imx8mp_blk_ctrl_data { struct imx8mp_blk_ctrl_data {
int max_reg; int max_reg;
int (*probe) (struct imx8mp_blk_ctrl *bc);
notifier_fn_t power_notifier_fn; notifier_fn_t power_notifier_fn;
void (*power_off) (struct imx8mp_blk_ctrl *bc, struct imx8mp_blk_ctrl_domain *domain); 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); 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) ...@@ -73,6 +85,92 @@ to_imx8mp_blk_ctrl_domain(struct generic_pm_domain *genpd)
return container_of(genpd, struct imx8mp_blk_ctrl_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, static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
struct imx8mp_blk_ctrl_domain *domain) struct imx8mp_blk_ctrl_domain *domain)
{ {
...@@ -187,6 +285,7 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { ...@@ -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 = { static const struct imx8mp_blk_ctrl_data imx8mp_hsio_blk_ctl_dev_data = {
.max_reg = 0x24, .max_reg = 0x24,
.probe = imx8mp_hsio_blk_ctrl_probe,
.power_on = imx8mp_hsio_blk_ctrl_power_on, .power_on = imx8mp_hsio_blk_ctrl_power_on,
.power_off = imx8mp_hsio_blk_ctrl_power_off, .power_off = imx8mp_hsio_blk_ctrl_power_off,
.power_notifier_fn = imx8mp_hsio_power_notifier, .power_notifier_fn = imx8mp_hsio_power_notifier,
...@@ -201,6 +300,7 @@ static const struct imx8mp_blk_ctrl_data imx8mp_hsio_blk_ctl_dev_data = { ...@@ -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_CTL3 0x70
#define HDMI_RTX_CLK_CTL4 0x80 #define HDMI_RTX_CLK_CTL4 0x80
#define HDMI_TX_CONTROL0 0x200 #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, static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
struct imx8mp_blk_ctrl_domain *domain) struct imx8mp_blk_ctrl_domain *domain)
...@@ -217,6 +317,8 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, ...@@ -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_CLK_CTL1, BIT(11));
regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0,
BIT(4) | BIT(5) | BIT(6)); BIT(4) | BIT(5) | BIT(6));
regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0,
FIELD_PREP(HDMI_LCDIF_NOC_HURRY_MASK, 7));
break; break;
case IMX8MP_HDMIBLK_PD_PAI: case IMX8MP_HDMIBLK_PD_PAI:
regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(17)); 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) ...@@ -634,6 +736,12 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
goto cleanup_provider; goto cleanup_provider;
} }
if (bc_data->probe) {
ret = bc_data->probe(bc);
if (ret)
goto cleanup_provider;
}
dev_set_drvdata(dev, bc); dev_set_drvdata(dev, bc);
return 0; return 0;
......
...@@ -164,7 +164,6 @@ MODULE_DEVICE_TABLE(of, imx93_pd_ids); ...@@ -164,7 +164,6 @@ MODULE_DEVICE_TABLE(of, imx93_pd_ids);
static struct platform_driver imx93_power_domain_driver = { static struct platform_driver imx93_power_domain_driver = {
.driver = { .driver = {
.name = "imx93_power_domain", .name = "imx93_power_domain",
.owner = THIS_MODULE,
.of_match_table = imx93_pd_ids, .of_match_table = imx93_pd_ids,
}, },
.probe = imx93_pd_probe, .probe = imx93_pd_probe,
......
...@@ -21,7 +21,6 @@ MODULE_DEVICE_TABLE(of, imx93_src_ids); ...@@ -21,7 +21,6 @@ MODULE_DEVICE_TABLE(of, imx93_src_ids);
static struct platform_driver imx93_src_driver = { static struct platform_driver imx93_src_driver = {
.driver = { .driver = {
.name = "imx93_src", .name = "imx93_src",
.owner = THIS_MODULE,
.of_match_table = imx93_src_ids, .of_match_table = imx93_src_ids,
}, },
.probe = imx93_src_probe, .probe = imx93_src_probe,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment