mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-05 07:30:06 -04:00
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: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user