1
linux/drivers/clk/qcom/videocc-sc7280.c
Linus Torvalds a4f9285520 This a large collection of clk driver updates and a handful of new SoC
clk driver support. We have the usual Qualcomm clk drivers, along with
 clk drivers for the Sophgo and T-Head vendors, all to support some new
 SoCs.
 
 Nothing in particular stands out to me in the updates. There's the
 interconnect clk driver which exposes clks as interconnects, crossing
 subsystems. There's a bunch of janitorial things that are improving
 drivers in general like kmemdup_array() or fixing error paths. But
 overall the updates look normal to fix the description data which is
 usually the stuff that's wrong and/or untested.
 
 I really wanted to land a bunch of KUnit clk code that I've been working
 on whenever I get some free time but it turned into a pumpkin at the
 last minute so I dropped those patches. I'll let it soak in linux-next
 after the merge window closes. I have a suspicion that we're going to
 need to totally rework the clk framework to fix structural issues like
 locking, clk rate setting, and runtime PM usage. Having a bunch of unit
 tests for that will help make sure that all keeps working.
 
 Core:
  - Skip gate basic type KUnit tests on s390 due to lack of MMIO emulation
 
 New Drivers:
  - AP sub-system clock controller in the T-Head TH1520
  - Sophgo Sophon sg2042 clk driver
  - Qualcomm SM7150 camera, display and video clk drivers
  - Qualcomm QCM2290 GPU clk driver
  - Qualcomm QCS8386/QCS8084 NSS clk driver
  - Qualcomm SM8650 camera and video drivers
 
 Updates:
  - Add reset support to Airoha EN7581 clk driver
  - Add MODULE_DESCRIPTIONs to various clk drivers
  - Introduce helper logic to expose clock controllers as simple
    interconnect providers
  - Use the interconnect helper above on Qualcomm ipq9574
  - Add CLK_SET_RATE_PARENT to the remaining USB pipe clocks on Qualcomm
    X1Elite
  - Improve error handling in Qualcomm kpss-xcc driver
  - Mark Qualcomm SC8280XP LPASS clock controller regmap_config const
  - Export more clocks for Rockchip rk3128 peripherals
  - Convert Rockchip clk drivers to use kmemdup_array()
  - Drop CLK_NR_CLKS from Rockchip rk3128 and rk3188 binding headers
  - Make qcom_cc_really_probe() take a struct device to allow reuse in
    non-platform-drivers
  - Introduce prepare-only branch clock ops in the qcom clk driver to
    support clocks on buses that take locks
  - Describe parent/child relationship for Qualcomm SC7280 camera GDSCs
  - Support Qualcomm Huayra 2290 alpha PLL
  - Adjust the highest SDCC clock frequency on Qualcomm IPQ6018 to match
    HS200 support
  - Add missing PCIe PIPE clocks on Qualcomm IPQ9574
  - Fix various configurations and properties in the Qualcomm SA8775P,
    X1E80100 and SM7280 drivers
  - Park Qualcomm SM8350 GPU RCGs on XO while disabled
  - Remove unused CONFIG_QCOM_RPMCC Kconfig symbol
  - exynos-clkout: Remove usage of of_device_id table as .of_match_table,
    because the driver is instantiated as MFD cell, not as standalone platform
    driver.  Populated .of_match_table confused people few times to convert the
    code to device_get_match_data(), which broke the driver
  - Mark one Samsung UFS clock as critical, because having it off stops the
    system from shutdown
  - Use kmemdup_array() when applicable
  - Remove unused 'struct gates_data' from old sunxi driver library
  - Add GPADC clock and reset for Allwinner H616
  - Minor Amlogic S4 clock fixes
  - DT bindings Yaml conversion of the Amlogic AXG audio controller
  - Amlogic C3 clock controllers support
  - Amlogic clk flag added to skip init of already enabled PLLs and avoid relocking
  - Amlogic A1 DT bindings updates for system pll support
  - Add missing MODULE_DESCRIPTION where necessary
  - Remove obsolete clock DT binding header files
  - Add Battery Backup (VBATTB) and I2C clocks, resets, and power
    domains on Renesas RZ/G3S
  - Add audio clocks on Renesas R-Car V4M
  - Add video capture (ISPCS, CSI-2, VIN) clocks on Renesas R-Car V4M
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmaZd3wRHHNib3lkQGtl
 cm5lbC5vcmcACgkQrQKIl8bklSVwCRAAz6leVJuGDmnyNvyq+BrXOHBI89/vAI1c
 ZejQLTKsXveI3fIQUTPAQ15XW1lRIPpPWRG09yZbVJ0P7WsNlfHA6KUjYiAaS9RN
 zkwLSI52ZulAhdRxBycIVMnfVOnoaJs4Vvp2jLdW+cRLj9BVwC1vXSDmWENvMrh2
 Om7W1r3+Utg/nO3eRVdM3+LZTfveUd6PWZnz/zp20sZLZRUeDA5DKj8fqg0dHuvZ
 auZ8byeELp39rFJqE9YO5fDH+kmzXL3CAHz8s8NEDA+BBD9S4w+mvEMjHSQfQdnB
 LetpZ9DPoYscnWgYS/KWCiodCIAq6ThVkkcX1lAmndPQDwPCKVOoBomNuRaNZvI8
 qJnP2ZhfWMbnrc291ECbPg82RjSOtp3ZzFij2T6jwDSsBc6pmJlwSwtvjtYC7fm+
 N1Ldrl2qz6BYdbqJWXBRApFdqcI8Z3aENrqpy98LJiPdGdwmcbPA2cAnEPzJENdo
 ggTYXC//oVoyA6xnA1vwJQDVR0TAAu8mm3brW3uYww0T46R7HOMhtaNqIcEc1fQU
 0k8mU4iW2xGQkeyR62afxDETKIe8/DMQUwoIwIZ1ogohHF+a8LmY+KnjAAmJK9LB
 yHhsQUOggmRe10vVfWxDSBZRyFuPblhCYTzytoAlEUs71jLJw7PF+CrF2ZZw8fP5
 OEE2/O5+XXU=
 =jEjn
 -----END PGP SIGNATURE-----

Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk updates from Stephen Boyd:
 "This a large collection of clk driver updates and a handful of new SoC
  clk driver support.

  We have the usual Qualcomm clk drivers, along with clk drivers for the
  Sophgo and T-Head vendors, all to support some new SoCs.

  Nothing in particular stands out to me in the updates. There's the
  interconnect clk driver which exposes clks as interconnects, crossing
  subsystems. There's a bunch of janitorial things that are improving
  drivers in general like kmemdup_array() or fixing error paths. But
  overall the updates look normal to fix the description data which is
  usually the stuff that's wrong and/or untested.

  Core:
   - Skip gate basic type KUnit tests on s390 due to lack of MMIO
     emulation

  New Drivers:
   - AP sub-system clock controller in the T-Head TH1520
   - Sophgo Sophon sg2042 clk driver
   - Qualcomm SM7150 camera, display and video clk drivers
   - Qualcomm QCM2290 GPU clk driver
   - Qualcomm QCS8386/QCS8084 NSS clk driver
   - Qualcomm SM8650 camera and video drivers

  Updates:
   - Add reset support to Airoha EN7581 clk driver
   - Add MODULE_DESCRIPTIONs to various clk drivers
   - Introduce helper logic to expose clock controllers as simple
     interconnect providers
   - Use the interconnect helper above on Qualcomm ipq9574
   - Add CLK_SET_RATE_PARENT to the remaining USB pipe clocks on
     Qualcomm X1Elite
   - Improve error handling in Qualcomm kpss-xcc driver
   - Mark Qualcomm SC8280XP LPASS clock controller regmap_config const
   - Export more clocks for Rockchip rk3128 peripherals
   - Convert Rockchip clk drivers to use kmemdup_array()
   - Drop CLK_NR_CLKS from Rockchip rk3128 and rk3188 binding headers
   - Make qcom_cc_really_probe() take a struct device to allow reuse in
     non-platform-drivers
   - Introduce prepare-only branch clock ops in the qcom clk driver to
     support clocks on buses that take locks
   - Describe parent/child relationship for Qualcomm SC7280 camera GDSCs
   - Support Qualcomm Huayra 2290 alpha PLL
   - Adjust the highest SDCC clock frequency on Qualcomm IPQ6018 to
     match HS200 support
   - Add missing PCIe PIPE clocks on Qualcomm IPQ9574
   - Fix various configurations and properties in the Qualcomm SA8775P,
     X1E80100 and SM7280 drivers
   - Park Qualcomm SM8350 GPU RCGs on XO while disabled
   - Remove unused CONFIG_QCOM_RPMCC Kconfig symbol
   - exynos-clkout: Remove usage of of_device_id table as
     .of_match_table, because the driver is instantiated as MFD cell,
     not as standalone platform driver. Populated .of_match_table
     confused people few times to convert the code to
     device_get_match_data(), which broke the driver
   - Mark one Samsung UFS clock as critical, because having it off stops
     the system from shutdown
   - Use kmemdup_array() when applicable
   - Remove unused 'struct gates_data' from old sunxi driver library
   - Add GPADC clock and reset for Allwinner H616
   - Minor Amlogic S4 clock fixes
   - DT bindings Yaml conversion of the Amlogic AXG audio controller
   - Amlogic C3 clock controllers support
   - Amlogic clk flag added to skip init of already enabled PLLs and
     avoid relocking
   - Amlogic A1 DT bindings updates for system pll support
   - Add missing MODULE_DESCRIPTION where necessary
   - Remove obsolete clock DT binding header files
   - Add Battery Backup (VBATTB) and I2C clocks, resets, and power
     domains on Renesas RZ/G3S
   - Add audio clocks on Renesas R-Car V4M
   - Add video capture (ISPCS, CSI-2, VIN) clocks on Renesas R-Car V4M"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (135 commits)
  clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks
  dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
  clk: sophgo: Avoid -Wsometimes-uninitialized in sg2042_clk_pll_set_rate()
  clk/sophgo: Using BUG() instead of unreachable() in mmux_get_parent_id()
  clk: mxs: Use clamp() in clk_ref_round_rate() and clk_ref_set_rate()
  clk: sunxi-ng r40: Constify struct regmap_config
  clk: en7523: fix rate divider for slic and spi clocks
  clk: lpc32xx: Constify struct regmap_config
  clk: xilinx: Constify struct regmap_config
  clk: en7523: Remove PCIe reset open drain configuration for EN7581
  clk: en7523: Remove pcie prepare/unpreare callbacks for EN7581 SoC
  clk: en7523: Add reset-controller support for EN7581 SoC
  dt-bindings: clock: airoha: Add reset support to EN7581 clock binding
  dt-bindings: clock: mediatek: Document reset cells for MT8188 sys
  clk: mediatek: mt8173-infracfg: Handle unallocated infracfg when module
  dt-bindings: clock: mediatek: add syscon compatible for mt7622 pciesys
  dt-bindings: clock: sprd,sc9860-clk: convert to YAML
  dt-bindings: clock: qoriq-clock: convert to yaml format
  clk: qcom: Park shared RCGs upon registration
  clk: qcom: ipq9574: Use icc-clk for enabling NoC related clocks
  ...
2024-07-19 12:16:28 -07:00

323 lines
7.8 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,videocc-sc7280.h>
#include "clk-alpha-pll.h"
#include "clk-branch.h"
#include "clk-rcg.h"
#include "common.h"
#include "reset.h"
#include "gdsc.h"
enum {
P_BI_TCXO,
P_SLEEP_CLK,
P_VIDEO_PLL0_OUT_EVEN,
};
static const struct pll_vco lucid_vco[] = {
{ 249600000, 2000000000, 0 },
};
/* 400MHz Configuration */
static const struct alpha_pll_config video_pll0_config = {
.l = 0x14,
.alpha = 0xD555,
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00002261,
.config_ctl_hi1_val = 0x329A299C,
.user_ctl_val = 0x00000001,
.user_ctl_hi_val = 0x00000805,
.user_ctl_hi1_val = 0x00000000,
};
static struct clk_alpha_pll video_pll0 = {
.offset = 0x0,
.vco_table = lucid_vco,
.num_vco = ARRAY_SIZE(lucid_vco),
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "video_pll0",
.parent_data = &(const struct clk_parent_data){
.fw_name = "bi_tcxo",
},
.num_parents = 1,
.ops = &clk_alpha_pll_lucid_ops,
},
},
};
static const struct parent_map video_cc_parent_map_0[] = {
{ P_BI_TCXO, 0 },
{ P_VIDEO_PLL0_OUT_EVEN, 3 },
};
static const struct clk_parent_data video_cc_parent_data_0[] = {
{ .fw_name = "bi_tcxo" },
{ .hw = &video_pll0.clkr.hw },
};
static const struct parent_map video_cc_parent_map_1[] = {
{ P_SLEEP_CLK, 0 },
};
static const struct clk_parent_data video_cc_parent_data_1[] = {
{ .fw_name = "sleep_clk" },
};
static const struct freq_tbl ftbl_video_cc_iris_clk_src[] = {
F(133333333, P_VIDEO_PLL0_OUT_EVEN, 3, 0, 0),
F(240000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
F(335000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
F(424000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
F(460000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
{ }
};
static struct clk_rcg2 video_cc_iris_clk_src = {
.cmd_rcgr = 0x1000,
.mnd_width = 0,
.hid_width = 5,
.parent_map = video_cc_parent_map_0,
.freq_tbl = ftbl_video_cc_iris_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "video_cc_iris_clk_src",
.parent_data = video_cc_parent_data_0,
.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_rcg2_shared_ops,
},
};
static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
F(32000, P_SLEEP_CLK, 1, 0, 0),
{ }
};
static struct clk_rcg2 video_cc_sleep_clk_src = {
.cmd_rcgr = 0x701c,
.mnd_width = 0,
.hid_width = 5,
.parent_map = video_cc_parent_map_1,
.freq_tbl = ftbl_video_cc_sleep_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "video_cc_sleep_clk_src",
.parent_data = video_cc_parent_data_1,
.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
.ops = &clk_rcg2_ops,
},
};
static struct clk_branch video_cc_iris_ahb_clk = {
.halt_reg = 0x5004,
.halt_check = BRANCH_HALT_VOTED,
.clkr = {
.enable_reg = 0x5004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_iris_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&video_cc_iris_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch video_cc_mvs0_axi_clk = {
.halt_reg = 0x800c,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x800c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_mvs0_axi_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch video_cc_mvs0_core_clk = {
.halt_reg = 0x3010,
.halt_check = BRANCH_HALT_VOTED,
.hwcg_reg = 0x3010,
.hwcg_bit = 1,
.clkr = {
.enable_reg = 0x3010,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_mvs0_core_clk",
.parent_hws = (const struct clk_hw*[]){
&video_cc_iris_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch video_cc_mvsc_core_clk = {
.halt_reg = 0x2014,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x2014,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_mvsc_core_clk",
.parent_hws = (const struct clk_hw*[]){
&video_cc_iris_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch video_cc_mvsc_ctl_axi_clk = {
.halt_reg = 0x8004,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x8004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_mvsc_ctl_axi_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch video_cc_sleep_clk = {
.halt_reg = 0x7034,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x7034,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_sleep_clk",
.parent_hws = (const struct clk_hw*[]){
&video_cc_sleep_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch video_cc_venus_ahb_clk = {
.halt_reg = 0x801c,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x801c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_venus_ahb_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct gdsc mvs0_gdsc = {
.gdscr = 0x3004,
.en_rest_wait_val = 0x2,
.en_few_wait_val = 0x2,
.clk_dis_wait_val = 0x6,
.pd = {
.name = "mvs0_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
.flags = HW_CTRL_TRIGGER | RETAIN_FF_ENABLE,
};
static struct gdsc mvsc_gdsc = {
.gdscr = 0x2004,
.en_rest_wait_val = 0x2,
.en_few_wait_val = 0x2,
.clk_dis_wait_val = 0x6,
.pd = {
.name = "mvsc_gdsc",
},
.flags = RETAIN_FF_ENABLE,
.pwrsts = PWRSTS_OFF_ON,
};
static struct clk_regmap *video_cc_sc7280_clocks[] = {
[VIDEO_CC_IRIS_AHB_CLK] = &video_cc_iris_ahb_clk.clkr,
[VIDEO_CC_IRIS_CLK_SRC] = &video_cc_iris_clk_src.clkr,
[VIDEO_CC_MVS0_AXI_CLK] = &video_cc_mvs0_axi_clk.clkr,
[VIDEO_CC_MVS0_CORE_CLK] = &video_cc_mvs0_core_clk.clkr,
[VIDEO_CC_MVSC_CORE_CLK] = &video_cc_mvsc_core_clk.clkr,
[VIDEO_CC_MVSC_CTL_AXI_CLK] = &video_cc_mvsc_ctl_axi_clk.clkr,
[VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr,
[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
[VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr,
[VIDEO_PLL0] = &video_pll0.clkr,
};
static struct gdsc *video_cc_sc7280_gdscs[] = {
[MVS0_GDSC] = &mvs0_gdsc,
[MVSC_GDSC] = &mvsc_gdsc,
};
static const struct regmap_config video_cc_sc7280_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0xb000,
.fast_io = true,
};
static const struct qcom_cc_desc video_cc_sc7280_desc = {
.config = &video_cc_sc7280_regmap_config,
.clks = video_cc_sc7280_clocks,
.num_clks = ARRAY_SIZE(video_cc_sc7280_clocks),
.gdscs = video_cc_sc7280_gdscs,
.num_gdscs = ARRAY_SIZE(video_cc_sc7280_gdscs),
};
static const struct of_device_id video_cc_sc7280_match_table[] = {
{ .compatible = "qcom,sc7280-videocc" },
{ }
};
MODULE_DEVICE_TABLE(of, video_cc_sc7280_match_table);
static int video_cc_sc7280_probe(struct platform_device *pdev)
{
struct regmap *regmap;
regmap = qcom_cc_map(pdev, &video_cc_sc7280_desc);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config);
return qcom_cc_really_probe(&pdev->dev, &video_cc_sc7280_desc, regmap);
}
static struct platform_driver video_cc_sc7280_driver = {
.probe = video_cc_sc7280_probe,
.driver = {
.name = "video_cc-sc7280",
.of_match_table = video_cc_sc7280_match_table,
},
};
module_platform_driver(video_cc_sc7280_driver);
MODULE_DESCRIPTION("QTI VIDEO_CC sc7280 Driver");
MODULE_LICENSE("GPL v2");