mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 16:01:44 -04:00
clk: qcom: gcc: Add multiple global clock controller driver for Nord SoC
The global clock controller on the Nord SoC is partitioned into GCC, SE_GCC, NE_GCC, and NW_GCC. Introduce driver support for each of these controllers. Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com> [Shawn: Drop include of <linux/of.h> as the driver doesn't use any OF APIs] Co-developed-by: Shawn Guo <shengchao.guo@oss.qualcomm.com> Signed-off-by: Shawn Guo <shengchao.guo@oss.qualcomm.com> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260403-nord-clks-v1-6-018af14979fd@oss.qualcomm.com [bjorn: Added missing .use_rpm to gcc_nord_desc] Signed-off-by: Bjorn Andersson <andersson@kernel.org>
This commit is contained in:
committed by
Bjorn Andersson
parent
cf6e6ac63c
commit
a4f780cd5c
@@ -145,6 +145,16 @@ config CLK_KAANAPALI_VIDEOCC
|
||||
Say Y if you want to support video devices and functionality such as
|
||||
video encode/decode.
|
||||
|
||||
config CLK_NORD_GCC
|
||||
tristate "Nord Global Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on Nord devices.
|
||||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination
|
||||
of GCC, SE_GCC, NE_GCC and NW_GCC.
|
||||
|
||||
config CLK_X1E80100_CAMCC
|
||||
tristate "X1E80100 Camera Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
@@ -35,6 +35,7 @@ obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o
|
||||
obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o
|
||||
obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o
|
||||
obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o
|
||||
obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o
|
||||
obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o
|
||||
obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o
|
||||
obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
|
||||
|
||||
1902
drivers/clk/qcom/gcc-nord.c
Normal file
1902
drivers/clk/qcom/gcc-nord.c
Normal file
File diff suppressed because it is too large
Load Diff
1987
drivers/clk/qcom/negcc-nord.c
Normal file
1987
drivers/clk/qcom/negcc-nord.c
Normal file
File diff suppressed because it is too large
Load Diff
688
drivers/clk/qcom/nwgcc-nord.c
Normal file
688
drivers/clk/qcom/nwgcc-nord.c
Normal file
@@ -0,0 +1,688 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,nord-nwgcc.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-pll.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-divider.h"
|
||||
#include "clk-regmap-mux.h"
|
||||
#include "common.h"
|
||||
#include "reset.h"
|
||||
|
||||
enum {
|
||||
DT_BI_TCXO,
|
||||
DT_SLEEP_CLK,
|
||||
};
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_NW_GCC_GPLL0_OUT_EVEN,
|
||||
P_NW_GCC_GPLL0_OUT_MAIN,
|
||||
P_SLEEP_CLK,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll nw_gcc_gpll0 = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
|
||||
.clkr = {
|
||||
.enable_reg = 0x0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpll0",
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.index = DT_BI_TCXO,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clk_div_table post_div_table_nw_gcc_gpll0_out_even[] = {
|
||||
{ 0x1, 2 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv nw_gcc_gpll0_out_even = {
|
||||
.offset = 0x0,
|
||||
.post_div_shift = 10,
|
||||
.post_div_table = post_div_table_nw_gcc_gpll0_out_even,
|
||||
.num_post_div = ARRAY_SIZE(post_div_table_nw_gcc_gpll0_out_even),
|
||||
.width = 4,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpll0_out_even",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gpll0.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map nw_gcc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_NW_GCC_GPLL0_OUT_MAIN, 1 },
|
||||
{ P_SLEEP_CLK, 5 },
|
||||
{ P_NW_GCC_GPLL0_OUT_EVEN, 6 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data nw_gcc_parent_data_0[] = {
|
||||
{ .index = DT_BI_TCXO },
|
||||
{ .hw = &nw_gcc_gpll0.clkr.hw },
|
||||
{ .index = DT_SLEEP_CLK },
|
||||
{ .hw = &nw_gcc_gpll0_out_even.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_nw_gcc_gp1_clk_src[] = {
|
||||
F(60000000, P_NW_GCC_GPLL0_OUT_MAIN, 10, 0, 0),
|
||||
F(100000000, P_NW_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||
F(200000000, P_NW_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 nw_gcc_gp1_clk_src = {
|
||||
.cmd_rcgr = 0x20004,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = nw_gcc_parent_map_0,
|
||||
.freq_tbl = ftbl_nw_gcc_gp1_clk_src,
|
||||
.hw_clk_ctrl = true,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gp1_clk_src",
|
||||
.parent_data = nw_gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(nw_gcc_parent_data_0),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 nw_gcc_gp2_clk_src = {
|
||||
.cmd_rcgr = 0x21004,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = nw_gcc_parent_map_0,
|
||||
.freq_tbl = ftbl_nw_gcc_gp1_clk_src,
|
||||
.hw_clk_ctrl = true,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gp2_clk_src",
|
||||
.parent_data = nw_gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(nw_gcc_parent_data_0),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_acmu_mux_clk = {
|
||||
.halt_reg = 0x1f01c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1f01c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_acmu_mux_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_camera_hf_axi_clk = {
|
||||
.halt_reg = 0x16008,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x16008,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x16008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_camera_hf_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_camera_sf_axi_clk = {
|
||||
.halt_reg = 0x1601c,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x1601c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1601c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_camera_sf_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_camera_trig_clk = {
|
||||
.halt_reg = 0x16034,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x16034,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x16034,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_camera_trig_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_disp_0_hf_axi_clk = {
|
||||
.halt_reg = 0x18008,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x18008,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x18008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_disp_0_hf_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_disp_0_trig_clk = {
|
||||
.halt_reg = 0x1801c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x1801c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1801c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_disp_0_trig_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_disp_1_hf_axi_clk = {
|
||||
.halt_reg = 0x19008,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x19008,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x19008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_disp_1_hf_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_disp_1_trig_clk = {
|
||||
.halt_reg = 0x1901c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x1901c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1901c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_disp_1_trig_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_dprx0_axi_hf_clk = {
|
||||
.halt_reg = 0x29004,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x29004,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x29004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_dprx0_axi_hf_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_dprx1_axi_hf_clk = {
|
||||
.halt_reg = 0x2a004,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x2a004,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2a004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_dprx1_axi_hf_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_eva_axi0_clk = {
|
||||
.halt_reg = 0x1b008,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x1b008,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1b008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_eva_axi0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_eva_axi0c_clk = {
|
||||
.halt_reg = 0x1b01c,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x1b01c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1b01c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_eva_axi0c_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_eva_trig_clk = {
|
||||
.halt_reg = 0x1b028,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x1b028,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1b028,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_eva_trig_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_frq_measure_ref_clk = {
|
||||
.halt_reg = 0x1f008,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1f008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_frq_measure_ref_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gp1_clk = {
|
||||
.halt_reg = 0x20000,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x20000,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gp1_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gp1_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gp2_clk = {
|
||||
.halt_reg = 0x21000,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x21000,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gp2_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gp2_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_2_gpll0_clk_src = {
|
||||
.halt_reg = 0x24150,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x24150,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x76000,
|
||||
.enable_mask = BIT(6),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_2_gpll0_clk_src",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gpll0.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_2_gpll0_div_clk_src = {
|
||||
.halt_reg = 0x24158,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x24158,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x76000,
|
||||
.enable_mask = BIT(7),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_2_gpll0_div_clk_src",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gpll0_out_even.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_2_hscnoc_gfx_clk = {
|
||||
.halt_reg = 0x2400c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x2400c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2400c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_2_hscnoc_gfx_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_gpll0_clk_src = {
|
||||
.halt_reg = 0x23150,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x23150,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x76000,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_gpll0_clk_src",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gpll0.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_gpll0_div_clk_src = {
|
||||
.halt_reg = 0x23158,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x23158,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x76000,
|
||||
.enable_mask = BIT(5),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_gpll0_div_clk_src",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&nw_gcc_gpll0_out_even.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_hscnoc_gfx_clk = {
|
||||
.halt_reg = 0x2300c,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x2300c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2300c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_hscnoc_gfx_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_gpu_smmu_vote_clk = {
|
||||
.halt_reg = 0x86038,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x86038,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_gpu_smmu_vote_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_hscnoc_gpu_2_axi_clk = {
|
||||
.halt_reg = 0x24160,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x24160,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x24160,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_hscnoc_gpu_2_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_hscnoc_gpu_axi_clk = {
|
||||
.halt_reg = 0x23160,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x23160,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x23160,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_hscnoc_gpu_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_mmu_1_tcu_vote_clk = {
|
||||
.halt_reg = 0x86040,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x86040,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_mmu_1_tcu_vote_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_video_axi0_clk = {
|
||||
.halt_reg = 0x1a008,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x1a008,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1a008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_video_axi0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_video_axi0c_clk = {
|
||||
.halt_reg = 0x1a01c,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x1a01c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1a01c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_video_axi0c_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch nw_gcc_video_axi1_clk = {
|
||||
.halt_reg = 0x1a030,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x1a030,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1a030,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "nw_gcc_video_axi1_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap *nw_gcc_nord_clocks[] = {
|
||||
[NW_GCC_ACMU_MUX_CLK] = &nw_gcc_acmu_mux_clk.clkr,
|
||||
[NW_GCC_CAMERA_HF_AXI_CLK] = &nw_gcc_camera_hf_axi_clk.clkr,
|
||||
[NW_GCC_CAMERA_SF_AXI_CLK] = &nw_gcc_camera_sf_axi_clk.clkr,
|
||||
[NW_GCC_CAMERA_TRIG_CLK] = &nw_gcc_camera_trig_clk.clkr,
|
||||
[NW_GCC_DISP_0_HF_AXI_CLK] = &nw_gcc_disp_0_hf_axi_clk.clkr,
|
||||
[NW_GCC_DISP_0_TRIG_CLK] = &nw_gcc_disp_0_trig_clk.clkr,
|
||||
[NW_GCC_DISP_1_HF_AXI_CLK] = &nw_gcc_disp_1_hf_axi_clk.clkr,
|
||||
[NW_GCC_DISP_1_TRIG_CLK] = &nw_gcc_disp_1_trig_clk.clkr,
|
||||
[NW_GCC_DPRX0_AXI_HF_CLK] = &nw_gcc_dprx0_axi_hf_clk.clkr,
|
||||
[NW_GCC_DPRX1_AXI_HF_CLK] = &nw_gcc_dprx1_axi_hf_clk.clkr,
|
||||
[NW_GCC_EVA_AXI0_CLK] = &nw_gcc_eva_axi0_clk.clkr,
|
||||
[NW_GCC_EVA_AXI0C_CLK] = &nw_gcc_eva_axi0c_clk.clkr,
|
||||
[NW_GCC_EVA_TRIG_CLK] = &nw_gcc_eva_trig_clk.clkr,
|
||||
[NW_GCC_FRQ_MEASURE_REF_CLK] = &nw_gcc_frq_measure_ref_clk.clkr,
|
||||
[NW_GCC_GP1_CLK] = &nw_gcc_gp1_clk.clkr,
|
||||
[NW_GCC_GP1_CLK_SRC] = &nw_gcc_gp1_clk_src.clkr,
|
||||
[NW_GCC_GP2_CLK] = &nw_gcc_gp2_clk.clkr,
|
||||
[NW_GCC_GP2_CLK_SRC] = &nw_gcc_gp2_clk_src.clkr,
|
||||
[NW_GCC_GPLL0] = &nw_gcc_gpll0.clkr,
|
||||
[NW_GCC_GPLL0_OUT_EVEN] = &nw_gcc_gpll0_out_even.clkr,
|
||||
[NW_GCC_GPU_2_GPLL0_CLK_SRC] = &nw_gcc_gpu_2_gpll0_clk_src.clkr,
|
||||
[NW_GCC_GPU_2_GPLL0_DIV_CLK_SRC] = &nw_gcc_gpu_2_gpll0_div_clk_src.clkr,
|
||||
[NW_GCC_GPU_2_HSCNOC_GFX_CLK] = &nw_gcc_gpu_2_hscnoc_gfx_clk.clkr,
|
||||
[NW_GCC_GPU_GPLL0_CLK_SRC] = &nw_gcc_gpu_gpll0_clk_src.clkr,
|
||||
[NW_GCC_GPU_GPLL0_DIV_CLK_SRC] = &nw_gcc_gpu_gpll0_div_clk_src.clkr,
|
||||
[NW_GCC_GPU_HSCNOC_GFX_CLK] = &nw_gcc_gpu_hscnoc_gfx_clk.clkr,
|
||||
[NW_GCC_GPU_SMMU_VOTE_CLK] = &nw_gcc_gpu_smmu_vote_clk.clkr,
|
||||
[NW_GCC_HSCNOC_GPU_2_AXI_CLK] = &nw_gcc_hscnoc_gpu_2_axi_clk.clkr,
|
||||
[NW_GCC_HSCNOC_GPU_AXI_CLK] = &nw_gcc_hscnoc_gpu_axi_clk.clkr,
|
||||
[NW_GCC_MMU_1_TCU_VOTE_CLK] = &nw_gcc_mmu_1_tcu_vote_clk.clkr,
|
||||
[NW_GCC_VIDEO_AXI0_CLK] = &nw_gcc_video_axi0_clk.clkr,
|
||||
[NW_GCC_VIDEO_AXI0C_CLK] = &nw_gcc_video_axi0c_clk.clkr,
|
||||
[NW_GCC_VIDEO_AXI1_CLK] = &nw_gcc_video_axi1_clk.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map nw_gcc_nord_resets[] = {
|
||||
[NW_GCC_CAMERA_BCR] = { 0x16000 },
|
||||
[NW_GCC_DISPLAY_0_BCR] = { 0x18000 },
|
||||
[NW_GCC_DISPLAY_1_BCR] = { 0x19000 },
|
||||
[NW_GCC_DPRX0_BCR] = { 0x29000 },
|
||||
[NW_GCC_DPRX1_BCR] = { 0x2a000 },
|
||||
[NW_GCC_EVA_BCR] = { 0x1b000 },
|
||||
[NW_GCC_GPU_2_BCR] = { 0x24000 },
|
||||
[NW_GCC_GPU_BCR] = { 0x23000 },
|
||||
[NW_GCC_VIDEO_BCR] = { 0x1a000 },
|
||||
};
|
||||
|
||||
static u32 nw_gcc_nord_critical_cbcrs[] = {
|
||||
0x16004, /* NW_GCC_CAMERA_AHB_CLK */
|
||||
0x16030, /* NW_GCC_CAMERA_XO_CLK */
|
||||
0x18004, /* NW_GCC_DISP_0_AHB_CLK */
|
||||
0x19004, /* NW_GCC_DISP_1_AHB_CLK */
|
||||
0x29018, /* NW_GCC_DPRX0_CFG_AHB_CLK */
|
||||
0x2a018, /* NW_GCC_DPRX1_CFG_AHB_CLK */
|
||||
0x1b004, /* NW_GCC_EVA_AHB_CLK */
|
||||
0x1b024, /* NW_GCC_EVA_XO_CLK */
|
||||
0x23004, /* NW_GCC_GPU_CFG_AHB_CLK */
|
||||
0x24004, /* NW_GCC_GPU_2_CFG_AHB_CLK */
|
||||
0x1a004, /* NW_GCC_VIDEO_AHB_CLK */
|
||||
0x1a044, /* NW_GCC_VIDEO_XO_CLK */
|
||||
};
|
||||
|
||||
static struct qcom_cc_driver_data nw_gcc_nord_driver_data = {
|
||||
.clk_cbcrs = nw_gcc_nord_critical_cbcrs,
|
||||
.num_clk_cbcrs = ARRAY_SIZE(nw_gcc_nord_critical_cbcrs),
|
||||
};
|
||||
|
||||
static const struct regmap_config nw_gcc_nord_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xf41f0,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc nw_gcc_nord_desc = {
|
||||
.config = &nw_gcc_nord_regmap_config,
|
||||
.clks = nw_gcc_nord_clocks,
|
||||
.num_clks = ARRAY_SIZE(nw_gcc_nord_clocks),
|
||||
.resets = nw_gcc_nord_resets,
|
||||
.num_resets = ARRAY_SIZE(nw_gcc_nord_resets),
|
||||
.driver_data = &nw_gcc_nord_driver_data,
|
||||
};
|
||||
|
||||
static const struct of_device_id nw_gcc_nord_match_table[] = {
|
||||
{ .compatible = "qcom,nord-nwgcc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, nw_gcc_nord_match_table);
|
||||
|
||||
static int nw_gcc_nord_probe(struct platform_device *pdev)
|
||||
{
|
||||
return qcom_cc_probe(pdev, &nw_gcc_nord_desc);
|
||||
}
|
||||
|
||||
static struct platform_driver nw_gcc_nord_driver = {
|
||||
.probe = nw_gcc_nord_probe,
|
||||
.driver = {
|
||||
.name = "nwgcc-nord",
|
||||
.of_match_table = nw_gcc_nord_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(nw_gcc_nord_driver);
|
||||
|
||||
MODULE_DESCRIPTION("QTI NWGCC NORD Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
1609
drivers/clk/qcom/segcc-nord.c
Normal file
1609
drivers/clk/qcom/segcc-nord.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user