diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-06 11:04:57 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-10-06 11:04:57 -0700 |
commit | ff6862c23d2e83d12d1759bf4337d41248fb4dc8 (patch) | |
tree | 36d499d2b2f807cd5c197267272fb310a4b0729a /drivers/soc/imx/imx8mp-blk-ctrl.c | |
parent | 40285e64c5654c956505dad34ed2ee4be163b1f0 (diff) | |
parent | 4413794917ba3ff42ade432870248b500253f152 (diff) | |
download | linux-ff6862c23d2e83d12d1759bf4337d41248fb4dc8.tar.bz2 |
Merge tag 'arm-drivers-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARM driver updates from Arnd Bergmann:
"The drivers branch for 6.1 is a bit larger than for most releases.
Most of the changes come from SoC maintainers for the drivers/soc
subsystem:
- A new driver for error handling on the NVIDIA Tegra 'control
backbone' bus.
- A new driver for Qualcomm LLCC/DDR bandwidth measurement
- New Rockchip rv1126 and rk3588 power domain drivers
- DT binding updates for memory controllers, older Rockchip SoCs,
various Mediatek devices, Qualcomm SCM firmware
- Minor updates to Hisilicon LPC bus, the Allwinner SRAM driver, the
Apple rtkit firmware driver, Tegra firmware
- Minor updates for SoC drivers (Samsung, Mediatek, Renesas, Tegra,
Qualcomm, Broadcom, NXP, ...)
There are also some separate subsystem with downstream maintainers
that merge updates this way:
- Various updates and new drivers in the memory controller subsystem
for Mediatek and Broadcom SoCs
- Small set of changes in preparation to add support for FF-A v1.1
specification later, in the Arm FF-A firmware subsystem
- debugfs support in the PSCI firmware subsystem"
* tag 'arm-drivers-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (149 commits)
ARM: remove check for CONFIG_DEBUG_LL_SER3
firmware/psci: Add debugfs support to ease debugging
firmware/psci: Print a warning if PSCI doesn't accept PC mode
dt-bindings: memory: snps,dw-umctl2-ddrc: Extend schema with IRQs/resets/clocks props
dt-bindings: memory: snps,dw-umctl2-ddrc: Replace opencoded numbers with macros
dt-bindings: memory: snps,dw-umctl2-ddrc: Use more descriptive device name
dt-bindings: memory: synopsys,ddrc-ecc: Detach Zynq DDRC controller support
soc: sunxi: sram: Add support for the D1 system control
soc: sunxi: sram: Export the LDO control register
soc: sunxi: sram: Save a pointer to the OF match data
soc: sunxi: sram: Return void from the release function
soc: apple: rtkit: Add apple_rtkit_poll
soc: imx: add i.MX93 media blk ctrl driver
soc: imx: add i.MX93 SRC power domain driver
soc: imx: imx8m-blk-ctrl: Use genpd_xlate_onecell
soc: imx: imx8mp-blk-ctrl: handle PCIe PHY resets
soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl
soc: imx: add i.MX8MP HDMI blk ctrl HDCP/HRV_MWR
soc: imx: add icc paths for i.MX8MP hsio/hdmi blk ctrl
soc: imx: add icc paths for i.MX8MP media blk ctrl
...
Diffstat (limited to 'drivers/soc/imx/imx8mp-blk-ctrl.c')
-rw-r--r-- | drivers/soc/imx/imx8mp-blk-ctrl.c | 89 |
1 files changed, 75 insertions, 14 deletions
diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 4ca2ede6871b..0e3b6ba22f94 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -6,6 +6,7 @@ #include <linux/clk.h> #include <linux/device.h> +#include <linux/interconnect.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/platform_device.h> @@ -18,6 +19,8 @@ #define GPR_REG0 0x0 #define PCIE_CLOCK_MODULE_EN BIT(0) #define USB_CLOCK_MODULE_EN BIT(1) +#define PCIE_PHY_APB_RST BIT(4) +#define PCIE_PHY_INIT_RST BIT(5) struct imx8mp_blk_ctrl_domain; @@ -36,17 +39,22 @@ struct imx8mp_blk_ctrl_domain_data { const char *name; const char * const *clk_names; int num_clks; + const char * const *path_names; + int num_paths; const char *gpc_name; }; #define DOMAIN_MAX_CLKS 2 +#define DOMAIN_MAX_PATHS 3 struct imx8mp_blk_ctrl_domain { struct generic_pm_domain genpd; const struct imx8mp_blk_ctrl_domain_data *data; struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; + struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; struct device *power_dev; struct imx8mp_blk_ctrl *bc; + int num_paths; int id; }; @@ -75,6 +83,10 @@ static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, case IMX8MP_HSIOBLK_PD_PCIE: regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); break; + case IMX8MP_HSIOBLK_PD_PCIE_PHY: + regmap_set_bits(bc->regmap, GPR_REG0, + PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST); + break; default: break; } @@ -90,6 +102,10 @@ static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, case IMX8MP_HSIOBLK_PD_PCIE: regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); break; + case IMX8MP_HSIOBLK_PD_PCIE_PHY: + regmap_clear_bits(bc->regmap, GPR_REG0, + PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST); + break; default: break; } @@ -144,6 +160,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { .clk_names = (const char *[]){ "usb" }, .num_clks = 1, .gpc_name = "usb", + .path_names = (const char *[]){"usb1", "usb2"}, + .num_paths = 2, }, [IMX8MP_HSIOBLK_PD_USB_PHY1] = { .name = "hsioblk-usb-phy1", @@ -158,6 +176,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { .clk_names = (const char *[]){ "pcie" }, .num_clks = 1, .gpc_name = "pcie", + .path_names = (const char *[]){"noc-pcie", "pcie"}, + .num_paths = 2, }, [IMX8MP_HSIOBLK_PD_PCIE_PHY] = { .name = "hsioblk-pcie-phy", @@ -225,6 +245,13 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); break; + case IMX8MP_HDMIBLK_PD_HDCP: + regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); + break; + case IMX8MP_HDMIBLK_PD_HRV: + regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); + regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); + break; default: break; } @@ -273,6 +300,13 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); break; + case IMX8MP_HDMIBLK_PD_HDCP: + regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); + break; + case IMX8MP_HDMIBLK_PD_HRV: + regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); + regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); + break; default: break; } @@ -322,6 +356,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { .clk_names = (const char *[]){ "axi", "apb" }, .num_clks = 2, .gpc_name = "lcdif", + .path_names = (const char *[]){"lcdif-hdmi"}, + .num_paths = 1, }, [IMX8MP_HDMIBLK_PD_PAI] = { .name = "hdmiblk-pai", @@ -353,6 +389,22 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { .num_clks = 2, .gpc_name = "hdmi-tx-phy", }, + [IMX8MP_HDMIBLK_PD_HRV] = { + .name = "hdmiblk-hrv", + .clk_names = (const char *[]){ "axi", "apb" }, + .num_clks = 2, + .gpc_name = "hrv", + .path_names = (const char *[]){"hrv"}, + .num_paths = 1, + }, + [IMX8MP_HDMIBLK_PD_HDCP] = { + .name = "hdmiblk-hdcp", + .clk_names = (const char *[]){ "axi", "apb" }, + .num_clks = 2, + .gpc_name = "hdcp", + .path_names = (const char *[]){"hdcp"}, + .num_paths = 1, + }, }; static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data = { @@ -395,6 +447,10 @@ static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain *genpd) goto clk_disable; } + ret = icc_bulk_set_bw(domain->num_paths, domain->paths); + if (ret) + dev_err(bc->dev, "failed to set icc bw\n"); + clk_bulk_disable_unprepare(data->num_clks, domain->clks); return 0; @@ -434,19 +490,6 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd) return 0; } -static struct generic_pm_domain * -imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data) -{ - struct genpd_onecell_data *onecell_data = data; - unsigned int index = args->args[0]; - - if (args->args_count != 1 || - index >= onecell_data->num_domains) - return ERR_PTR(-EINVAL); - - return onecell_data->domains[index]; -} - static struct lock_class_key blk_ctrl_genpd_lock_class; static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) @@ -489,7 +532,6 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) return -ENOMEM; bc->onecell_data.num_domains = num_domains; - bc->onecell_data.xlate = imx8m_blk_ctrl_xlate; bc->onecell_data.domains = devm_kcalloc(dev, num_domains, sizeof(struct generic_pm_domain *), GFP_KERNEL); @@ -510,10 +552,29 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) int j; domain->data = data; + domain->num_paths = data->num_paths; for (j = 0; j < data->num_clks; j++) domain->clks[j].id = data->clk_names[j]; + for (j = 0; j < data->num_paths; j++) { + domain->paths[j].name = data->path_names[j]; + /* Fake value for now, just let ICC could configure NoC mode/priority */ + domain->paths[j].avg_bw = 1; + domain->paths[j].peak_bw = 1; + } + + ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths); + if (ret) { + if (ret != -EPROBE_DEFER) { + dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n"); + domain->num_paths = 0; + } else { + dev_err_probe(dev, ret, "failed to get noc entries\n"); + goto cleanup_pds; + } + } + ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); if (ret) { dev_err_probe(dev, ret, "failed to get clock\n"); |