mirror of
https://github.com/torvalds/linux.git
synced 2024-11-13 07:31:45 +00:00
Merge branches 'clk-spreadtrum', 'clk-mvebu-dvfs', 'clk-qoriq', 'clk-imx' and 'clk-qcom-ipq8074' into clk-next
* clk-spreadtrum: clk: sprd: add clocks support for SC9860 clk: sprd: Add dt-bindings include file for SC9860 dt-bindings: Add Spreadtrum clock binding documentation clk: sprd: add adjustable pll support clk: sprd: add composite clock support clk: sprd: add divider clock support clk: sprd: add mux clock support clk: sprd: add gate clock support clk: sprd: Add common infrastructure clk: move clock common macros out from vendor directories * clk-mvebu-dvfs: clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks clk: mvebu: armada-37xx-periph: prepare cpu clk to be used with DVFS clk: mvebu: armada-37xx-periph: cosmetic changes * clk-qoriq: clk: qoriq: add more divider clocks support * clk-imx: clk: imx51: uart4, uart5 gates only exist on imx50, imx53 * clk-qcom-ipq8074: clk: qcom: ipq8074: add misc resets for PCIE and NSS dt-bindings: clock: qcom: add misc resets for PCIE and NSS clk: qcom: ipq8074: add GP and Crypto clocks clk: qcom: ipq8074: add NSS ethernet port clocks clk: qcom: ipq8074: add NSS clocks clk: qcom: ipq8074: add PCIE, USB and SDCC clocks clk: qcom: ipq8074: add remaining PLL’s dt-bindings: clock: qcom: add remaining clocks for IPQ8074 clk: qcom: ipq8074: fix missing GPLL0 divider width clk: qcom: add parent map for regmap mux clk: qcom: add read-only divider operations
This commit is contained in:
commit
21170e3bda
@ -78,6 +78,7 @@ second cell is the clock index for the specified type.
|
||||
2 hwaccel index (n in CLKCGnHWACSR)
|
||||
3 fman 0 for fm1, 1 for fm2
|
||||
4 platform pll 0=pll, 1=pll/2, 2=pll/3, 3=pll/4
|
||||
4=pll/5, 5=pll/6, 6=pll/7, 7=pll/8
|
||||
5 coreclk must be 0
|
||||
|
||||
3. Example
|
||||
|
63
Documentation/devicetree/bindings/clock/sprd.txt
Normal file
63
Documentation/devicetree/bindings/clock/sprd.txt
Normal file
@ -0,0 +1,63 @@
|
||||
Spreadtrum Clock Binding
|
||||
------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: should contain the following compatible strings:
|
||||
- "sprd,sc9860-pmu-gate"
|
||||
- "sprd,sc9860-pll"
|
||||
- "sprd,sc9860-ap-clk"
|
||||
- "sprd,sc9860-aon-prediv"
|
||||
- "sprd,sc9860-apahb-gate"
|
||||
- "sprd,sc9860-aon-gate"
|
||||
- "sprd,sc9860-aonsecure-clk"
|
||||
- "sprd,sc9860-agcp-gate"
|
||||
- "sprd,sc9860-gpu-clk"
|
||||
- "sprd,sc9860-vsp-clk"
|
||||
- "sprd,sc9860-vsp-gate"
|
||||
- "sprd,sc9860-cam-clk"
|
||||
- "sprd,sc9860-cam-gate"
|
||||
- "sprd,sc9860-disp-clk"
|
||||
- "sprd,sc9860-disp-gate"
|
||||
- "sprd,sc9860-apapb-gate"
|
||||
|
||||
- #clock-cells: must be 1
|
||||
|
||||
- clocks : Should be the input parent clock(s) phandle for the clock, this
|
||||
property here just simply shows which clock group the clocks'
|
||||
parents are in, since each clk node would represent many clocks
|
||||
which are defined in the driver. The detailed dependency
|
||||
relationship (i.e. how many parents and which are the parents)
|
||||
are implemented in driver code.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reg: Contain the registers base address and length. It must be configured
|
||||
only if no 'sprd,syscon' under the node.
|
||||
|
||||
- sprd,syscon: phandle to the syscon which is in the same address area with
|
||||
the clock, and so we can get regmap for the clocks from the
|
||||
syscon device.
|
||||
|
||||
Example:
|
||||
|
||||
pmu_gate: pmu-gate {
|
||||
compatible = "sprd,sc9860-pmu-gate";
|
||||
sprd,syscon = <&pmu_regs>;
|
||||
clocks = <&ext_26m>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
pll: pll {
|
||||
compatible = "sprd,sc9860-pll";
|
||||
sprd,syscon = <&ana_regs>;
|
||||
clocks = <&pmu_gate 0>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
ap_clk: clock-controller@20000000 {
|
||||
compatible = "sprd,sc9860-ap-clk";
|
||||
reg = <0 0x20000000 0 0x400>;
|
||||
clocks = <&ext_26m>, <&pll 0>,
|
||||
<&pmu_gate 0>;
|
||||
#clock-cells = <1>;
|
||||
};
|
@ -236,6 +236,7 @@ source "drivers/clk/mvebu/Kconfig"
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
source "drivers/clk/renesas/Kconfig"
|
||||
source "drivers/clk/samsung/Kconfig"
|
||||
source "drivers/clk/sprd/Kconfig"
|
||||
source "drivers/clk/sunxi-ng/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
|
@ -85,6 +85,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_ARCH_SIRF) += sirf/
|
||||
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
|
||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-$(CONFIG_ARCH_SPRD) += sprd/
|
||||
obj-$(CONFIG_ARCH_STI) += st/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
|
||||
|
@ -41,7 +41,7 @@ struct clockgen_pll_div {
|
||||
};
|
||||
|
||||
struct clockgen_pll {
|
||||
struct clockgen_pll_div div[4];
|
||||
struct clockgen_pll_div div[8];
|
||||
};
|
||||
|
||||
#define CLKSEL_VALID 1
|
||||
@ -1127,6 +1127,13 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* For platform PLL, there are 8 divider clocks.
|
||||
* For core PLL, there are 4 divider clocks at most.
|
||||
*/
|
||||
if (idx != PLATFORM_PLL && i >= 4)
|
||||
break;
|
||||
|
||||
snprintf(pll->div[i].name, sizeof(pll->div[i].name),
|
||||
"cg-pll%d-div%d", idx, i + 1);
|
||||
|
||||
|
@ -257,10 +257,6 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
|
||||
clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
|
||||
clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
|
||||
clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
|
||||
clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
|
||||
clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
|
||||
clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
|
||||
clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
|
||||
clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
|
||||
|
||||
clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
|
||||
@ -361,6 +357,10 @@ static void __init mx50_clocks_init(struct device_node *np)
|
||||
clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
|
||||
clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
|
||||
clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
|
||||
clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
|
||||
clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
|
||||
clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
|
||||
clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
|
||||
|
||||
clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
|
||||
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
|
||||
@ -562,6 +562,10 @@ static void __init mx53_clocks_init(struct device_node *np)
|
||||
clk[IMX5_CLK_IEEE1588_PRED] = imx_clk_divider("ieee1588_pred", "ieee1588_sel", MXC_CCM_CSCDR2, 6, 3);
|
||||
clk[IMX5_CLK_IEEE1588_PODF] = imx_clk_divider("ieee1588_podf", "ieee1588_pred", MXC_CCM_CSCDR2, 0, 6);
|
||||
clk[IMX5_CLK_IEEE1588_GATE] = imx_clk_gate2("ieee1588_serial_gate", "ieee1588_podf", MXC_CCM_CCGR7, 6);
|
||||
clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
|
||||
clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
|
||||
clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
|
||||
clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
|
||||
|
||||
clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
|
||||
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
|
||||
|
@ -21,9 +21,11 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define TBG_SEL 0x0
|
||||
@ -33,6 +35,26 @@
|
||||
#define CLK_SEL 0x10
|
||||
#define CLK_DIS 0x14
|
||||
|
||||
#define LOAD_LEVEL_NR 4
|
||||
|
||||
#define ARMADA_37XX_NB_L0L1 0x18
|
||||
#define ARMADA_37XX_NB_L2L3 0x1C
|
||||
#define ARMADA_37XX_NB_TBG_DIV_OFF 13
|
||||
#define ARMADA_37XX_NB_TBG_DIV_MASK 0x7
|
||||
#define ARMADA_37XX_NB_CLK_SEL_OFF 11
|
||||
#define ARMADA_37XX_NB_CLK_SEL_MASK 0x1
|
||||
#define ARMADA_37XX_NB_TBG_SEL_OFF 9
|
||||
#define ARMADA_37XX_NB_TBG_SEL_MASK 0x3
|
||||
#define ARMADA_37XX_NB_CONFIG_SHIFT 16
|
||||
#define ARMADA_37XX_NB_DYN_MOD 0x24
|
||||
#define ARMADA_37XX_NB_DFS_EN 31
|
||||
#define ARMADA_37XX_NB_CPU_LOAD 0x30
|
||||
#define ARMADA_37XX_NB_CPU_LOAD_MASK 0x3
|
||||
#define ARMADA_37XX_DVFS_LOAD_0 0
|
||||
#define ARMADA_37XX_DVFS_LOAD_1 1
|
||||
#define ARMADA_37XX_DVFS_LOAD_2 2
|
||||
#define ARMADA_37XX_DVFS_LOAD_3 3
|
||||
|
||||
struct clk_periph_driver_data {
|
||||
struct clk_hw_onecell_data *hw_data;
|
||||
spinlock_t lock;
|
||||
@ -46,7 +68,18 @@ struct clk_double_div {
|
||||
u8 shift2;
|
||||
};
|
||||
|
||||
struct clk_pm_cpu {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg_mux;
|
||||
u8 shift_mux;
|
||||
u32 mask_mux;
|
||||
void __iomem *reg_div;
|
||||
u8 shift_div;
|
||||
struct regmap *nb_pm_base;
|
||||
};
|
||||
|
||||
#define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw)
|
||||
#define to_clk_pm_cpu(_hw) container_of(_hw, struct clk_pm_cpu, hw)
|
||||
|
||||
struct clk_periph_data {
|
||||
const char *name;
|
||||
@ -55,6 +88,7 @@ struct clk_periph_data {
|
||||
struct clk_hw *mux_hw;
|
||||
struct clk_hw *rate_hw;
|
||||
struct clk_hw *gate_hw;
|
||||
struct clk_hw *muxrate_hw;
|
||||
bool is_double_div;
|
||||
};
|
||||
|
||||
@ -79,7 +113,9 @@ static const struct clk_div_table clk_table2[] = {
|
||||
{ .val = 1, .div = 4, },
|
||||
{ .val = 0, .div = 0, }, /* last entry */
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_double_div_ops;
|
||||
static const struct clk_ops clk_pm_cpu_ops;
|
||||
|
||||
#define PERIPH_GATE(_name, _bit) \
|
||||
struct clk_gate gate_##_name = { \
|
||||
@ -121,6 +157,18 @@ struct clk_divider rate_##_name = { \
|
||||
} \
|
||||
};
|
||||
|
||||
#define PERIPH_PM_CPU(_name, _shift1, _reg, _shift2) \
|
||||
struct clk_pm_cpu muxrate_##_name = { \
|
||||
.reg_mux = (void *)TBG_SEL, \
|
||||
.mask_mux = 3, \
|
||||
.shift_mux = _shift1, \
|
||||
.reg_div = (void *)_reg, \
|
||||
.shift_div = _shift2, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.ops = &clk_pm_cpu_ops, \
|
||||
} \
|
||||
};
|
||||
|
||||
#define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\
|
||||
static PERIPH_GATE(_name, _bit); \
|
||||
static PERIPH_MUX(_name, _shift); \
|
||||
@ -135,10 +183,6 @@ static PERIPH_DIV(_name, _reg, _shift1, _table);
|
||||
static PERIPH_GATE(_name, _bit); \
|
||||
static PERIPH_DIV(_name, _reg, _shift, _table);
|
||||
|
||||
#define PERIPH_CLK_MUX_DIV(_name, _shift, _reg, _shift_div, _table) \
|
||||
static PERIPH_MUX(_name, _shift); \
|
||||
static PERIPH_DIV(_name, _reg, _shift_div, _table);
|
||||
|
||||
#define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\
|
||||
static PERIPH_MUX(_name, _shift); \
|
||||
static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
|
||||
@ -179,13 +223,12 @@ static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
|
||||
.rate_hw = &rate_##_name.hw, \
|
||||
}
|
||||
|
||||
#define REF_CLK_MUX_DIV(_name) \
|
||||
#define REF_CLK_PM_CPU(_name) \
|
||||
{ .name = #_name, \
|
||||
.parent_names = (const char *[]){ "TBG-A-P", \
|
||||
"TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
|
||||
.num_parents = 4, \
|
||||
.mux_hw = &mux_##_name.hw, \
|
||||
.rate_hw = &rate_##_name.hw, \
|
||||
.muxrate_hw = &muxrate_##_name.hw, \
|
||||
}
|
||||
|
||||
#define REF_CLK_MUX_DD(_name) \
|
||||
@ -215,9 +258,9 @@ PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV_SEL0, DIV_SEL0, 15, 12);
|
||||
PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6);
|
||||
PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6);
|
||||
PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19);
|
||||
PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6);
|
||||
static PERIPH_PM_CPU(cpu, 22, DIV_SEL0, 28);
|
||||
|
||||
static struct clk_periph_data data_nb[] ={
|
||||
static struct clk_periph_data data_nb[] = {
|
||||
REF_CLK_FULL_DD(mmc),
|
||||
REF_CLK_FULL_DD(sata_host),
|
||||
REF_CLK_FULL_DD(sec_at),
|
||||
@ -234,7 +277,7 @@ static struct clk_periph_data data_nb[] ={
|
||||
REF_CLK_FULL(trace),
|
||||
REF_CLK_FULL(counter),
|
||||
REF_CLK_FULL_DD(eip97),
|
||||
REF_CLK_MUX_DIV(cpu),
|
||||
REF_CLK_PM_CPU(cpu),
|
||||
{ },
|
||||
};
|
||||
|
||||
@ -281,7 +324,7 @@ static unsigned int get_div(void __iomem *reg, int shift)
|
||||
}
|
||||
|
||||
static unsigned long clk_double_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_double_div *double_div = to_clk_double_div(hw);
|
||||
unsigned int div;
|
||||
@ -296,6 +339,222 @@ static const struct clk_ops clk_double_div_ops = {
|
||||
.recalc_rate = clk_double_div_recalc_rate,
|
||||
};
|
||||
|
||||
static void armada_3700_pm_dvfs_update_regs(unsigned int load_level,
|
||||
unsigned int *reg,
|
||||
unsigned int *offset)
|
||||
{
|
||||
if (load_level <= ARMADA_37XX_DVFS_LOAD_1)
|
||||
*reg = ARMADA_37XX_NB_L0L1;
|
||||
else
|
||||
*reg = ARMADA_37XX_NB_L2L3;
|
||||
|
||||
if (load_level == ARMADA_37XX_DVFS_LOAD_0 ||
|
||||
load_level == ARMADA_37XX_DVFS_LOAD_2)
|
||||
*offset += ARMADA_37XX_NB_CONFIG_SHIFT;
|
||||
}
|
||||
|
||||
static bool armada_3700_pm_dvfs_is_enabled(struct regmap *base)
|
||||
{
|
||||
unsigned int val, reg = ARMADA_37XX_NB_DYN_MOD;
|
||||
|
||||
if (IS_ERR(base))
|
||||
return false;
|
||||
|
||||
regmap_read(base, reg, &val);
|
||||
|
||||
return !!(val & BIT(ARMADA_37XX_NB_DFS_EN));
|
||||
}
|
||||
|
||||
static unsigned int armada_3700_pm_dvfs_get_cpu_div(struct regmap *base)
|
||||
{
|
||||
unsigned int reg = ARMADA_37XX_NB_CPU_LOAD;
|
||||
unsigned int offset = ARMADA_37XX_NB_TBG_DIV_OFF;
|
||||
unsigned int load_level, div;
|
||||
|
||||
/*
|
||||
* This function is always called after the function
|
||||
* armada_3700_pm_dvfs_is_enabled, so no need to check again
|
||||
* if the base is valid.
|
||||
*/
|
||||
regmap_read(base, reg, &load_level);
|
||||
|
||||
/*
|
||||
* The register and the offset inside this register accessed to
|
||||
* read the current divider depend on the load level
|
||||
*/
|
||||
load_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
|
||||
armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
|
||||
|
||||
regmap_read(base, reg, &div);
|
||||
|
||||
return (div >> offset) & ARMADA_37XX_NB_TBG_DIV_MASK;
|
||||
}
|
||||
|
||||
static unsigned int armada_3700_pm_dvfs_get_cpu_parent(struct regmap *base)
|
||||
{
|
||||
unsigned int reg = ARMADA_37XX_NB_CPU_LOAD;
|
||||
unsigned int offset = ARMADA_37XX_NB_TBG_SEL_OFF;
|
||||
unsigned int load_level, sel;
|
||||
|
||||
/*
|
||||
* This function is always called after the function
|
||||
* armada_3700_pm_dvfs_is_enabled, so no need to check again
|
||||
* if the base is valid
|
||||
*/
|
||||
regmap_read(base, reg, &load_level);
|
||||
|
||||
/*
|
||||
* The register and the offset inside this register accessed to
|
||||
* read the current divider depend on the load level
|
||||
*/
|
||||
load_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
|
||||
armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
|
||||
|
||||
regmap_read(base, reg, &sel);
|
||||
|
||||
return (sel >> offset) & ARMADA_37XX_NB_TBG_SEL_MASK;
|
||||
}
|
||||
|
||||
static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
|
||||
int num_parents = clk_hw_get_num_parents(hw);
|
||||
u32 val;
|
||||
|
||||
if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) {
|
||||
val = armada_3700_pm_dvfs_get_cpu_parent(pm_cpu->nb_pm_base);
|
||||
} else {
|
||||
val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux;
|
||||
val &= pm_cpu->mask_mux;
|
||||
}
|
||||
|
||||
if (val >= num_parents)
|
||||
return -EINVAL;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int clk_pm_cpu_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
|
||||
struct regmap *base = pm_cpu->nb_pm_base;
|
||||
int load_level;
|
||||
|
||||
/*
|
||||
* We set the clock parent only if the DVFS is available but
|
||||
* not enabled.
|
||||
*/
|
||||
if (IS_ERR(base) || armada_3700_pm_dvfs_is_enabled(base))
|
||||
return -EINVAL;
|
||||
|
||||
/* Set the parent clock for all the load level */
|
||||
for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
|
||||
unsigned int reg, mask, val,
|
||||
offset = ARMADA_37XX_NB_TBG_SEL_OFF;
|
||||
|
||||
armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
|
||||
|
||||
val = index << offset;
|
||||
mask = ARMADA_37XX_NB_TBG_SEL_MASK << offset;
|
||||
regmap_update_bits(base, reg, mask, val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
|
||||
unsigned int div;
|
||||
|
||||
if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base))
|
||||
div = armada_3700_pm_dvfs_get_cpu_div(pm_cpu->nb_pm_base);
|
||||
else
|
||||
div = get_div(pm_cpu->reg_div, pm_cpu->shift_div);
|
||||
return DIV_ROUND_UP_ULL((u64)parent_rate, div);
|
||||
}
|
||||
|
||||
static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
|
||||
struct regmap *base = pm_cpu->nb_pm_base;
|
||||
unsigned int div = *parent_rate / rate;
|
||||
unsigned int load_level;
|
||||
/* only available when DVFS is enabled */
|
||||
if (!armada_3700_pm_dvfs_is_enabled(base))
|
||||
return -EINVAL;
|
||||
|
||||
for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
|
||||
unsigned int reg, val, offset = ARMADA_37XX_NB_TBG_DIV_OFF;
|
||||
|
||||
armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
|
||||
|
||||
regmap_read(base, reg, &val);
|
||||
|
||||
val >>= offset;
|
||||
val &= ARMADA_37XX_NB_TBG_DIV_MASK;
|
||||
if (val == div)
|
||||
/*
|
||||
* We found a load level matching the target
|
||||
* divider, switch to this load level and
|
||||
* return.
|
||||
*/
|
||||
return *parent_rate / div;
|
||||
}
|
||||
|
||||
/* We didn't find any valid divider */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
|
||||
struct regmap *base = pm_cpu->nb_pm_base;
|
||||
unsigned int div = parent_rate / rate;
|
||||
unsigned int load_level;
|
||||
|
||||
/* only available when DVFS is enabled */
|
||||
if (!armada_3700_pm_dvfs_is_enabled(base))
|
||||
return -EINVAL;
|
||||
|
||||
for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) {
|
||||
unsigned int reg, mask, val,
|
||||
offset = ARMADA_37XX_NB_TBG_DIV_OFF;
|
||||
|
||||
armada_3700_pm_dvfs_update_regs(load_level, ®, &offset);
|
||||
|
||||
regmap_read(base, reg, &val);
|
||||
val >>= offset;
|
||||
val &= ARMADA_37XX_NB_TBG_DIV_MASK;
|
||||
|
||||
if (val == div) {
|
||||
/*
|
||||
* We found a load level matching the target
|
||||
* divider, switch to this load level and
|
||||
* return.
|
||||
*/
|
||||
reg = ARMADA_37XX_NB_CPU_LOAD;
|
||||
mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
|
||||
regmap_update_bits(base, reg, mask, load_level);
|
||||
|
||||
return rate;
|
||||
}
|
||||
}
|
||||
|
||||
/* We didn't find any valid divider */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pm_cpu_ops = {
|
||||
.get_parent = clk_pm_cpu_get_parent,
|
||||
.set_parent = clk_pm_cpu_set_parent,
|
||||
.round_rate = clk_pm_cpu_round_rate,
|
||||
.set_rate = clk_pm_cpu_set_rate,
|
||||
.recalc_rate = clk_pm_cpu_recalc_rate,
|
||||
};
|
||||
|
||||
static const struct of_device_id armada_3700_periph_clock_of_match[] = {
|
||||
{ .compatible = "marvell,armada-3700-periph-clock-nb",
|
||||
.data = data_nb, },
|
||||
@ -303,6 +562,7 @@ static const struct of_device_id armada_3700_periph_clock_of_match[] = {
|
||||
.data = data_sb, },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
|
||||
void __iomem *reg, spinlock_t *lock,
|
||||
struct device *dev, struct clk_hw **hw)
|
||||
@ -354,10 +614,29 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
|
||||
}
|
||||
}
|
||||
|
||||
if (data->muxrate_hw) {
|
||||
struct clk_pm_cpu *pmcpu_clk;
|
||||
struct clk_hw *muxrate_hw = data->muxrate_hw;
|
||||
struct regmap *map;
|
||||
|
||||
pmcpu_clk = to_clk_pm_cpu(muxrate_hw);
|
||||
pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux;
|
||||
pmcpu_clk->reg_div = reg + (u64)pmcpu_clk->reg_div;
|
||||
|
||||
mux_hw = muxrate_hw;
|
||||
rate_hw = muxrate_hw;
|
||||
mux_ops = muxrate_hw->init->ops;
|
||||
rate_ops = muxrate_hw->init->ops;
|
||||
|
||||
map = syscon_regmap_lookup_by_compatible(
|
||||
"marvell,armada-3700-nb-pm");
|
||||
pmcpu_clk->nb_pm_base = map;
|
||||
}
|
||||
|
||||
*hw = clk_hw_register_composite(dev, data->name, data->parent_names,
|
||||
data->num_parents, mux_hw,
|
||||
mux_ops, rate_hw, rate_ops,
|
||||
gate_hw, gate_ops, CLK_IGNORE_UNUSED);
|
||||
data->num_parents, mux_hw,
|
||||
mux_ops, rate_hw, rate_ops,
|
||||
gate_hw, gate_ops, CLK_IGNORE_UNUSED);
|
||||
|
||||
if (IS_ERR(*hw))
|
||||
return PTR_ERR(*hw);
|
||||
@ -406,12 +685,11 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev)
|
||||
if (armada_3700_add_composite_clk(&data[i], reg,
|
||||
&driver_data->lock, dev, hw))
|
||||
dev_err(dev, "Can't register periph clock %s\n",
|
||||
data[i].name);
|
||||
|
||||
data[i].name);
|
||||
}
|
||||
|
||||
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
|
||||
driver_data->hw_data);
|
||||
driver_data->hw_data);
|
||||
if (ret) {
|
||||
for (i = 0; i < num_periph; i++)
|
||||
clk_hw_unregister(driver_data->hw_data->hws[i]);
|
||||
|
@ -25,16 +25,6 @@ struct freq_tbl {
|
||||
u16 n;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct parent_map - map table for PLL source select configuration values
|
||||
* @src: source PLL
|
||||
* @cfg: configuration value
|
||||
*/
|
||||
struct parent_map {
|
||||
u8 src;
|
||||
u8 cfg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mn - M/N:D counter
|
||||
* @mnctr_en_bit: bit to enable mn counter
|
||||
|
@ -23,6 +23,29 @@ static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
|
||||
return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
|
||||
}
|
||||
|
||||
static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct clk_regmap_div *divider = to_clk_regmap_div(hw);
|
||||
struct clk_regmap *clkr = ÷r->clkr;
|
||||
u32 div;
|
||||
struct clk_hw *hw_parent = clk_hw_get_parent(hw);
|
||||
|
||||
regmap_read(clkr->regmap, divider->reg, &div);
|
||||
div >>= divider->shift;
|
||||
div &= BIT(divider->width) - 1;
|
||||
div += 1;
|
||||
|
||||
if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
|
||||
if (!hw_parent)
|
||||
return -EINVAL;
|
||||
|
||||
*prate = clk_hw_round_rate(hw_parent, rate * div);
|
||||
}
|
||||
|
||||
return DIV_ROUND_UP_ULL((u64)*prate, div);
|
||||
}
|
||||
|
||||
static long div_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
@ -68,3 +91,9 @@ const struct clk_ops clk_regmap_div_ops = {
|
||||
.recalc_rate = div_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
|
||||
|
||||
const struct clk_ops clk_regmap_div_ro_ops = {
|
||||
.round_rate = div_round_ro_rate,
|
||||
.recalc_rate = div_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops);
|
||||
|
@ -25,5 +25,6 @@ struct clk_regmap_div {
|
||||
};
|
||||
|
||||
extern const struct clk_ops clk_regmap_div_ops;
|
||||
extern const struct clk_ops clk_regmap_div_ro_ops;
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,9 @@ static u8 mux_get_parent(struct clk_hw *hw)
|
||||
val >>= mux->shift;
|
||||
val &= mask;
|
||||
|
||||
if (mux->parent_map)
|
||||
return qcom_find_src_index(hw, mux->parent_map, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -45,6 +48,9 @@ static int mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
|
||||
unsigned int val;
|
||||
|
||||
if (mux->parent_map)
|
||||
index = mux->parent_map[index].cfg;
|
||||
|
||||
val = index;
|
||||
val <<= mux->shift;
|
||||
|
||||
|
@ -16,11 +16,13 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include "clk-regmap.h"
|
||||
#include "common.h"
|
||||
|
||||
struct clk_regmap_mux {
|
||||
u32 reg;
|
||||
u32 shift;
|
||||
u32 width;
|
||||
const struct parent_map *parent_map;
|
||||
struct clk_regmap clkr;
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,6 @@ struct qcom_reset_map;
|
||||
struct regmap;
|
||||
struct freq_tbl;
|
||||
struct clk_hw;
|
||||
struct parent_map;
|
||||
|
||||
#define PLL_LOCK_COUNT_SHIFT 8
|
||||
#define PLL_LOCK_COUNT_MASK 0x3f
|
||||
@ -39,6 +38,16 @@ struct qcom_cc_desc {
|
||||
size_t num_gdscs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct parent_map - map table for source select configuration values
|
||||
* @src: source
|
||||
* @cfg: configuration value
|
||||
*/
|
||||
struct parent_map {
|
||||
u8 src;
|
||||
u8 cfg;
|
||||
};
|
||||
|
||||
extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
|
||||
unsigned long rate);
|
||||
extern const struct freq_tbl *qcom_find_freq_floor(const struct freq_tbl *f,
|
||||
|
File diff suppressed because it is too large
Load Diff
14
drivers/clk/sprd/Kconfig
Normal file
14
drivers/clk/sprd/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
config SPRD_COMMON_CLK
|
||||
tristate "Clock support for Spreadtrum SoCs"
|
||||
depends on ARCH_SPRD || COMPILE_TEST
|
||||
default ARCH_SPRD
|
||||
|
||||
if SPRD_COMMON_CLK
|
||||
|
||||
# SoC Drivers
|
||||
|
||||
config SPRD_SC9860_CLK
|
||||
tristate "Support for the Spreadtrum SC9860 clocks"
|
||||
depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST
|
||||
default ARM64 && ARCH_SPRD
|
||||
endif
|
11
drivers/clk/sprd/Makefile
Normal file
11
drivers/clk/sprd/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
obj-$(CONFIG_SPRD_COMMON_CLK) += clk-sprd.o
|
||||
|
||||
clk-sprd-y += common.o
|
||||
clk-sprd-y += gate.o
|
||||
clk-sprd-y += mux.o
|
||||
clk-sprd-y += div.o
|
||||
clk-sprd-y += composite.o
|
||||
clk-sprd-y += pll.o
|
||||
|
||||
## SoC support
|
||||
obj-$(CONFIG_SPRD_SC9860_CLK) += sc9860-clk.o
|
96
drivers/clk/sprd/common.c
Normal file
96
drivers/clk/sprd/common.c
Normal file
@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum clock infrastructure
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static const struct regmap_config sprdclk_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xffff,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static void sprd_clk_set_regmap(const struct sprd_clk_desc *desc,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
int i;
|
||||
struct sprd_clk_common *cclk;
|
||||
|
||||
for (i = 0; i < desc->num_clk_clks; i++) {
|
||||
cclk = desc->clk_clks[i];
|
||||
if (!cclk)
|
||||
continue;
|
||||
|
||||
cclk->regmap = regmap;
|
||||
}
|
||||
}
|
||||
|
||||
int sprd_clk_regmap_init(struct platform_device *pdev,
|
||||
const struct sprd_clk_desc *desc)
|
||||
{
|
||||
void __iomem *base;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct regmap *regmap;
|
||||
|
||||
if (of_find_property(node, "sprd,syscon", NULL)) {
|
||||
regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon");
|
||||
if (IS_ERR_OR_NULL(regmap)) {
|
||||
pr_err("%s: failed to get syscon regmap\n", __func__);
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
} else {
|
||||
base = of_iomap(node, 0);
|
||||
regmap = devm_regmap_init_mmio(&pdev->dev, base,
|
||||
&sprdclk_regmap_config);
|
||||
if (IS_ERR_OR_NULL(regmap)) {
|
||||
pr_err("failed to init regmap\n");
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
}
|
||||
|
||||
sprd_clk_set_regmap(desc, regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_clk_regmap_init);
|
||||
|
||||
int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw)
|
||||
{
|
||||
int i, ret;
|
||||
struct clk_hw *hw;
|
||||
|
||||
for (i = 0; i < clkhw->num; i++) {
|
||||
|
||||
hw = clkhw->hws[i];
|
||||
|
||||
if (!hw)
|
||||
continue;
|
||||
|
||||
ret = devm_clk_hw_register(dev, hw);
|
||||
if (ret) {
|
||||
dev_err(dev, "Couldn't register clock %d - %s\n",
|
||||
i, hw->init->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clkhw);
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to add clock provider\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_clk_probe);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
38
drivers/clk/sprd/common.h
Normal file
38
drivers/clk/sprd/common.h
Normal file
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum clock infrastructure
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#ifndef _SPRD_CLK_COMMON_H_
|
||||
#define _SPRD_CLK_COMMON_H_
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
struct device_node;
|
||||
|
||||
struct sprd_clk_common {
|
||||
struct regmap *regmap;
|
||||
u32 reg;
|
||||
struct clk_hw hw;
|
||||
};
|
||||
|
||||
struct sprd_clk_desc {
|
||||
struct sprd_clk_common **clk_clks;
|
||||
unsigned long num_clk_clks;
|
||||
struct clk_hw_onecell_data *hw_clks;
|
||||
};
|
||||
|
||||
static inline struct sprd_clk_common *
|
||||
hw_to_sprd_clk_common(const struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct sprd_clk_common, hw);
|
||||
}
|
||||
int sprd_clk_regmap_init(struct platform_device *pdev,
|
||||
const struct sprd_clk_desc *desc);
|
||||
int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw);
|
||||
|
||||
#endif /* _SPRD_CLK_COMMON_H_ */
|
60
drivers/clk/sprd/composite.c
Normal file
60
drivers/clk/sprd/composite.c
Normal file
@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum composite clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "composite.h"
|
||||
|
||||
static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct sprd_comp *cc = hw_to_sprd_comp(hw);
|
||||
|
||||
return sprd_div_helper_round_rate(&cc->common, &cc->div,
|
||||
rate, parent_rate);
|
||||
}
|
||||
|
||||
static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sprd_comp *cc = hw_to_sprd_comp(hw);
|
||||
|
||||
return sprd_div_helper_recalc_rate(&cc->common, &cc->div, parent_rate);
|
||||
}
|
||||
|
||||
static int sprd_comp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sprd_comp *cc = hw_to_sprd_comp(hw);
|
||||
|
||||
return sprd_div_helper_set_rate(&cc->common, &cc->div,
|
||||
rate, parent_rate);
|
||||
}
|
||||
|
||||
static u8 sprd_comp_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_comp *cc = hw_to_sprd_comp(hw);
|
||||
|
||||
return sprd_mux_helper_get_parent(&cc->common, &cc->mux);
|
||||
}
|
||||
|
||||
static int sprd_comp_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct sprd_comp *cc = hw_to_sprd_comp(hw);
|
||||
|
||||
return sprd_mux_helper_set_parent(&cc->common, &cc->mux, index);
|
||||
}
|
||||
|
||||
const struct clk_ops sprd_comp_ops = {
|
||||
.get_parent = sprd_comp_get_parent,
|
||||
.set_parent = sprd_comp_set_parent,
|
||||
|
||||
.round_rate = sprd_comp_round_rate,
|
||||
.recalc_rate = sprd_comp_recalc_rate,
|
||||
.set_rate = sprd_comp_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sprd_comp_ops);
|
51
drivers/clk/sprd/composite.h
Normal file
51
drivers/clk/sprd/composite.h
Normal file
@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum composite clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#ifndef _SPRD_COMPOSITE_H_
|
||||
#define _SPRD_COMPOSITE_H_
|
||||
|
||||
#include "common.h"
|
||||
#include "mux.h"
|
||||
#include "div.h"
|
||||
|
||||
struct sprd_comp {
|
||||
struct sprd_mux_ssel mux;
|
||||
struct sprd_div_internal div;
|
||||
struct sprd_clk_common common;
|
||||
};
|
||||
|
||||
#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \
|
||||
_mshift, _mwidth, _dshift, _dwidth, _flags) \
|
||||
struct sprd_comp _struct = { \
|
||||
.mux = _SPRD_MUX_CLK(_mshift, _mwidth, _table), \
|
||||
.div = _SPRD_DIV_CLK(_dshift, _dwidth), \
|
||||
.common = { \
|
||||
.regmap = NULL, \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS(_name, \
|
||||
_parent, \
|
||||
&sprd_comp_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift, \
|
||||
_mwidth, _dshift, _dwidth, _flags) \
|
||||
SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, \
|
||||
NULL, _mshift, _mwidth, \
|
||||
_dshift, _dwidth, _flags)
|
||||
|
||||
static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
|
||||
|
||||
return container_of(common, struct sprd_comp, common);
|
||||
}
|
||||
|
||||
extern const struct clk_ops sprd_comp_ops;
|
||||
|
||||
#endif /* _SPRD_COMPOSITE_H_ */
|
90
drivers/clk/sprd/div.c
Normal file
90
drivers/clk/sprd/div.c
Normal file
@ -0,0 +1,90 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum divider clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "div.h"
|
||||
|
||||
long sprd_div_helper_round_rate(struct sprd_clk_common *common,
|
||||
const struct sprd_div_internal *div,
|
||||
unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
return divider_round_rate(&common->hw, rate, parent_rate,
|
||||
NULL, div->width, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
|
||||
|
||||
static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct sprd_div *cd = hw_to_sprd_div(hw);
|
||||
|
||||
return sprd_div_helper_round_rate(&cd->common, &cd->div,
|
||||
rate, parent_rate);
|
||||
}
|
||||
|
||||
unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
|
||||
const struct sprd_div_internal *div,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned int reg;
|
||||
|
||||
regmap_read(common->regmap, common->reg, ®);
|
||||
val = reg >> div->shift;
|
||||
val &= (1 << div->width) - 1;
|
||||
|
||||
return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate);
|
||||
|
||||
static unsigned long sprd_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sprd_div *cd = hw_to_sprd_div(hw);
|
||||
|
||||
return sprd_div_helper_recalc_rate(&cd->common, &cd->div, parent_rate);
|
||||
}
|
||||
|
||||
int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
|
||||
const struct sprd_div_internal *div,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
unsigned long val;
|
||||
unsigned int reg;
|
||||
|
||||
val = divider_get_val(rate, parent_rate, NULL,
|
||||
div->width, 0);
|
||||
|
||||
regmap_read(common->regmap, common->reg, ®);
|
||||
reg &= ~GENMASK(div->width + div->shift - 1, div->shift);
|
||||
|
||||
regmap_write(common->regmap, common->reg,
|
||||
reg | (val << div->shift));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate);
|
||||
|
||||
static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sprd_div *cd = hw_to_sprd_div(hw);
|
||||
|
||||
return sprd_div_helper_set_rate(&cd->common, &cd->div,
|
||||
rate, parent_rate);
|
||||
}
|
||||
|
||||
const struct clk_ops sprd_div_ops = {
|
||||
.recalc_rate = sprd_div_recalc_rate,
|
||||
.round_rate = sprd_div_round_rate,
|
||||
.set_rate = sprd_div_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sprd_div_ops);
|
75
drivers/clk/sprd/div.h
Normal file
75
drivers/clk/sprd/div.h
Normal file
@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum divider clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#ifndef _SPRD_DIV_H_
|
||||
#define _SPRD_DIV_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* struct sprd_div_internal - Internal divider description
|
||||
* @shift: Bit offset of the divider in its register
|
||||
* @width: Width of the divider field in its register
|
||||
*
|
||||
* That structure represents a single divider, and is meant to be
|
||||
* embedded in other structures representing the various clock
|
||||
* classes.
|
||||
*/
|
||||
struct sprd_div_internal {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
};
|
||||
|
||||
#define _SPRD_DIV_CLK(_shift, _width) \
|
||||
{ \
|
||||
.shift = _shift, \
|
||||
.width = _width, \
|
||||
}
|
||||
|
||||
struct sprd_div {
|
||||
struct sprd_div_internal div;
|
||||
struct sprd_clk_common common;
|
||||
};
|
||||
|
||||
#define SPRD_DIV_CLK(_struct, _name, _parent, _reg, \
|
||||
_shift, _width, _flags) \
|
||||
struct sprd_div _struct = { \
|
||||
.div = _SPRD_DIV_CLK(_shift, _width), \
|
||||
.common = { \
|
||||
.regmap = NULL, \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&sprd_div_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
static inline struct sprd_div *hw_to_sprd_div(const struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
|
||||
|
||||
return container_of(common, struct sprd_div, common);
|
||||
}
|
||||
|
||||
long sprd_div_helper_round_rate(struct sprd_clk_common *common,
|
||||
const struct sprd_div_internal *div,
|
||||
unsigned long rate,
|
||||
unsigned long *parent_rate);
|
||||
|
||||
unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
|
||||
const struct sprd_div_internal *div,
|
||||
unsigned long parent_rate);
|
||||
|
||||
int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
|
||||
const struct sprd_div_internal *div,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
|
||||
extern const struct clk_ops sprd_div_ops;
|
||||
|
||||
#endif /* _SPRD_DIV_H_ */
|
111
drivers/clk/sprd/gate.c
Normal file
111
drivers/clk/sprd/gate.c
Normal file
@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum gate clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "gate.h"
|
||||
|
||||
static void clk_gate_toggle(const struct sprd_gate *sg, bool en)
|
||||
{
|
||||
const struct sprd_clk_common *common = &sg->common;
|
||||
unsigned int reg;
|
||||
bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? true : false;
|
||||
|
||||
set ^= en;
|
||||
|
||||
regmap_read(common->regmap, common->reg, ®);
|
||||
|
||||
if (set)
|
||||
reg |= sg->enable_mask;
|
||||
else
|
||||
reg &= ~sg->enable_mask;
|
||||
|
||||
regmap_write(common->regmap, common->reg, reg);
|
||||
}
|
||||
|
||||
static void clk_sc_gate_toggle(const struct sprd_gate *sg, bool en)
|
||||
{
|
||||
const struct sprd_clk_common *common = &sg->common;
|
||||
bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
|
||||
unsigned int offset;
|
||||
|
||||
set ^= en;
|
||||
|
||||
/*
|
||||
* Each set/clear gate clock has three registers:
|
||||
* common->reg - base register
|
||||
* common->reg + offset - set register
|
||||
* common->reg + 2 * offset - clear register
|
||||
*/
|
||||
offset = set ? sg->sc_offset : sg->sc_offset * 2;
|
||||
|
||||
regmap_write(common->regmap, common->reg + offset,
|
||||
sg->enable_mask);
|
||||
}
|
||||
|
||||
static void sprd_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_gate *sg = hw_to_sprd_gate(hw);
|
||||
|
||||
clk_gate_toggle(sg, false);
|
||||
}
|
||||
|
||||
static int sprd_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_gate *sg = hw_to_sprd_gate(hw);
|
||||
|
||||
clk_gate_toggle(sg, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sprd_sc_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_gate *sg = hw_to_sprd_gate(hw);
|
||||
|
||||
clk_sc_gate_toggle(sg, false);
|
||||
}
|
||||
|
||||
static int sprd_sc_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_gate *sg = hw_to_sprd_gate(hw);
|
||||
|
||||
clk_sc_gate_toggle(sg, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int sprd_gate_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_gate *sg = hw_to_sprd_gate(hw);
|
||||
struct sprd_clk_common *common = &sg->common;
|
||||
unsigned int reg;
|
||||
|
||||
regmap_read(common->regmap, common->reg, ®);
|
||||
|
||||
if (sg->flags & CLK_GATE_SET_TO_DISABLE)
|
||||
reg ^= sg->enable_mask;
|
||||
|
||||
reg &= sg->enable_mask;
|
||||
|
||||
return reg ? 1 : 0;
|
||||
}
|
||||
|
||||
const struct clk_ops sprd_gate_ops = {
|
||||
.disable = sprd_gate_disable,
|
||||
.enable = sprd_gate_enable,
|
||||
.is_enabled = sprd_gate_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sprd_gate_ops);
|
||||
|
||||
const struct clk_ops sprd_sc_gate_ops = {
|
||||
.disable = sprd_sc_gate_disable,
|
||||
.enable = sprd_sc_gate_enable,
|
||||
.is_enabled = sprd_gate_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sprd_sc_gate_ops);
|
||||
|
59
drivers/clk/sprd/gate.h
Normal file
59
drivers/clk/sprd/gate.h
Normal file
@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum gate clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#ifndef _SPRD_GATE_H_
|
||||
#define _SPRD_GATE_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct sprd_gate {
|
||||
u32 enable_mask;
|
||||
u16 flags;
|
||||
u16 sc_offset;
|
||||
|
||||
struct sprd_clk_common common;
|
||||
};
|
||||
|
||||
#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \
|
||||
_enable_mask, _flags, _gate_flags, _ops) \
|
||||
struct sprd_gate _struct = { \
|
||||
.enable_mask = _enable_mask, \
|
||||
.sc_offset = _sc_offset, \
|
||||
.flags = _gate_flags, \
|
||||
.common = { \
|
||||
.regmap = NULL, \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPRD_GATE_CLK(_struct, _name, _parent, _reg, \
|
||||
_enable_mask, _flags, _gate_flags) \
|
||||
SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, 0, \
|
||||
_enable_mask, _flags, _gate_flags, \
|
||||
&sprd_gate_ops)
|
||||
|
||||
#define SPRD_SC_GATE_CLK(_struct, _name, _parent, _reg, _sc_offset, \
|
||||
_enable_mask, _flags, _gate_flags) \
|
||||
SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset, \
|
||||
_enable_mask, _flags, _gate_flags, \
|
||||
&sprd_sc_gate_ops)
|
||||
|
||||
static inline struct sprd_gate *hw_to_sprd_gate(const struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
|
||||
|
||||
return container_of(common, struct sprd_gate, common);
|
||||
}
|
||||
|
||||
extern const struct clk_ops sprd_gate_ops;
|
||||
extern const struct clk_ops sprd_sc_gate_ops;
|
||||
|
||||
#endif /* _SPRD_GATE_H_ */
|
76
drivers/clk/sprd/mux.c
Normal file
76
drivers/clk/sprd/mux.c
Normal file
@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum multiplexer clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "mux.h"
|
||||
|
||||
u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
|
||||
const struct sprd_mux_ssel *mux)
|
||||
{
|
||||
unsigned int reg;
|
||||
u8 parent;
|
||||
int num_parents;
|
||||
int i;
|
||||
|
||||
regmap_read(common->regmap, common->reg, ®);
|
||||
parent = reg >> mux->shift;
|
||||
parent &= (1 << mux->width) - 1;
|
||||
|
||||
if (!mux->table)
|
||||
return parent;
|
||||
|
||||
num_parents = clk_hw_get_num_parents(&common->hw);
|
||||
|
||||
for (i = 0; i < num_parents - 1; i++)
|
||||
if (parent >= mux->table[i] && parent < mux->table[i + 1])
|
||||
return i;
|
||||
|
||||
return num_parents - 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent);
|
||||
|
||||
static u8 sprd_mux_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_mux *cm = hw_to_sprd_mux(hw);
|
||||
|
||||
return sprd_mux_helper_get_parent(&cm->common, &cm->mux);
|
||||
}
|
||||
|
||||
int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
|
||||
const struct sprd_mux_ssel *mux,
|
||||
u8 index)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
if (mux->table)
|
||||
index = mux->table[index];
|
||||
|
||||
regmap_read(common->regmap, common->reg, ®);
|
||||
reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
|
||||
regmap_write(common->regmap, common->reg,
|
||||
reg | (index << mux->shift));
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent);
|
||||
|
||||
static int sprd_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct sprd_mux *cm = hw_to_sprd_mux(hw);
|
||||
|
||||
return sprd_mux_helper_set_parent(&cm->common, &cm->mux, index);
|
||||
}
|
||||
|
||||
const struct clk_ops sprd_mux_ops = {
|
||||
.get_parent = sprd_mux_get_parent,
|
||||
.set_parent = sprd_mux_set_parent,
|
||||
.determine_rate = __clk_mux_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sprd_mux_ops);
|
74
drivers/clk/sprd/mux.h
Normal file
74
drivers/clk/sprd/mux.h
Normal file
@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum multiplexer clock driver
|
||||
//
|
||||
// Copyright (C) 2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#ifndef _SPRD_MUX_H_
|
||||
#define _SPRD_MUX_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* struct sprd_mux_ssel - Mux clock's source select bits in its register
|
||||
* @shift: Bit offset of the divider in its register
|
||||
* @width: Width of the divider field in its register
|
||||
* @table: For some mux clocks, not all sources are used on some special
|
||||
* chips, this matches the value of mux clock's register and the
|
||||
* sources which are used for this mux clock
|
||||
*/
|
||||
struct sprd_mux_ssel {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
const u8 *table;
|
||||
};
|
||||
|
||||
struct sprd_mux {
|
||||
struct sprd_mux_ssel mux;
|
||||
struct sprd_clk_common common;
|
||||
};
|
||||
|
||||
#define _SPRD_MUX_CLK(_shift, _width, _table) \
|
||||
{ \
|
||||
.shift = _shift, \
|
||||
.width = _width, \
|
||||
.table = _table, \
|
||||
}
|
||||
|
||||
#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table, \
|
||||
_reg, _shift, _width, \
|
||||
_flags) \
|
||||
struct sprd_mux _struct = { \
|
||||
.mux = _SPRD_MUX_CLK(_shift, _width, _table), \
|
||||
.common = { \
|
||||
.regmap = NULL, \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS(_name, \
|
||||
_parents, \
|
||||
&sprd_mux_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPRD_MUX_CLK(_struct, _name, _parents, _reg, \
|
||||
_shift, _width, _flags) \
|
||||
SPRD_MUX_CLK_TABLE(_struct, _name, _parents, NULL, \
|
||||
_reg, _shift, _width, _flags)
|
||||
|
||||
static inline struct sprd_mux *hw_to_sprd_mux(const struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
|
||||
|
||||
return container_of(common, struct sprd_mux, common);
|
||||
}
|
||||
|
||||
extern const struct clk_ops sprd_mux_ops;
|
||||
|
||||
u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
|
||||
const struct sprd_mux_ssel *mux);
|
||||
int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
|
||||
const struct sprd_mux_ssel *mux,
|
||||
u8 index);
|
||||
|
||||
#endif /* _SPRD_MUX_H_ */
|
266
drivers/clk/sprd/pll.c
Normal file
266
drivers/clk/sprd/pll.c
Normal file
@ -0,0 +1,266 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum pll clock driver
|
||||
//
|
||||
// Copyright (C) 2015~2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "pll.h"
|
||||
|
||||
#define CLK_PLL_1M 1000000
|
||||
#define CLK_PLL_10M (CLK_PLL_1M * 10)
|
||||
|
||||
#define pindex(pll, member) \
|
||||
(pll->factors[member].shift / (8 * sizeof(pll->regs_num)))
|
||||
|
||||
#define pshift(pll, member) \
|
||||
(pll->factors[member].shift % (8 * sizeof(pll->regs_num)))
|
||||
|
||||
#define pwidth(pll, member) \
|
||||
pll->factors[member].width
|
||||
|
||||
#define pmask(pll, member) \
|
||||
((pwidth(pll, member)) ? \
|
||||
GENMASK(pwidth(pll, member) + pshift(pll, member) - 1, \
|
||||
pshift(pll, member)) : 0)
|
||||
|
||||
#define pinternal(pll, cfg, member) \
|
||||
(cfg[pindex(pll, member)] & pmask(pll, member))
|
||||
|
||||
#define pinternal_val(pll, cfg, member) \
|
||||
(pinternal(pll, cfg, member) >> pshift(pll, member))
|
||||
|
||||
static inline unsigned int
|
||||
sprd_pll_read(const struct sprd_pll *pll, u8 index)
|
||||
{
|
||||
const struct sprd_clk_common *common = &pll->common;
|
||||
unsigned int val = 0;
|
||||
|
||||
if (WARN_ON(index >= pll->regs_num))
|
||||
return 0;
|
||||
|
||||
regmap_read(common->regmap, common->reg + index * 4, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void
|
||||
sprd_pll_write(const struct sprd_pll *pll, u8 index,
|
||||
u32 msk, u32 val)
|
||||
{
|
||||
const struct sprd_clk_common *common = &pll->common;
|
||||
unsigned int offset, reg;
|
||||
int ret = 0;
|
||||
|
||||
if (WARN_ON(index >= pll->regs_num))
|
||||
return;
|
||||
|
||||
offset = common->reg + index * 4;
|
||||
ret = regmap_read(common->regmap, offset, ®);
|
||||
if (!ret)
|
||||
regmap_write(common->regmap, offset, (reg & ~msk) | val);
|
||||
}
|
||||
|
||||
static unsigned long pll_get_refin(const struct sprd_pll *pll)
|
||||
{
|
||||
u32 shift, mask, index, refin_id = 3;
|
||||
const unsigned long refin[4] = { 2, 4, 13, 26 };
|
||||
|
||||
if (pwidth(pll, PLL_REFIN)) {
|
||||
index = pindex(pll, PLL_REFIN);
|
||||
shift = pshift(pll, PLL_REFIN);
|
||||
mask = pmask(pll, PLL_REFIN);
|
||||
refin_id = (sprd_pll_read(pll, index) & mask) >> shift;
|
||||
if (refin_id > 3)
|
||||
refin_id = 3;
|
||||
}
|
||||
|
||||
return refin[refin_id];
|
||||
}
|
||||
|
||||
static u32 pll_get_ibias(u64 rate, const u64 *table)
|
||||
{
|
||||
u32 i, num = table[0];
|
||||
|
||||
for (i = 1; i < num + 1; i++)
|
||||
if (rate <= table[i])
|
||||
break;
|
||||
|
||||
return (i == num + 1) ? num : i;
|
||||
}
|
||||
|
||||
static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
u32 *cfg;
|
||||
u32 i, mask, regs_num = pll->regs_num;
|
||||
unsigned long rate, nint, kint = 0;
|
||||
u64 refin;
|
||||
u16 k1, k2;
|
||||
|
||||
cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
|
||||
if (!cfg)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < regs_num; i++)
|
||||
cfg[i] = sprd_pll_read(pll, i);
|
||||
|
||||
refin = pll_get_refin(pll);
|
||||
|
||||
if (pinternal(pll, cfg, PLL_PREDIV))
|
||||
refin = refin * 2;
|
||||
|
||||
if (pwidth(pll, PLL_POSTDIV) &&
|
||||
((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
|
||||
(!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV))))
|
||||
refin = refin / 2;
|
||||
|
||||
if (!pinternal(pll, cfg, PLL_DIV_S)) {
|
||||
rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
|
||||
} else {
|
||||
nint = pinternal_val(pll, cfg, PLL_NINT);
|
||||
if (pinternal(pll, cfg, PLL_SDM_EN))
|
||||
kint = pinternal_val(pll, cfg, PLL_KINT);
|
||||
|
||||
mask = pmask(pll, PLL_KINT);
|
||||
|
||||
k1 = pll->k1;
|
||||
k2 = pll->k2;
|
||||
rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
|
||||
((mask >> __ffs(mask)) + 1)) *
|
||||
k2 + refin * nint * CLK_PLL_1M;
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
#define SPRD_PLL_WRITE_CHECK(pll, i, mask, val) \
|
||||
(((sprd_pll_read(pll, i) & mask) == val) ? 0 : (-EFAULT))
|
||||
|
||||
static int _sprd_pll_set_rate(const struct sprd_pll *pll,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct reg_cfg *cfg;
|
||||
int ret = 0;
|
||||
u32 mask, shift, width, ibias_val, index;
|
||||
u32 regs_num = pll->regs_num, i = 0;
|
||||
unsigned long kint, nint;
|
||||
u64 tmp, refin, fvco = rate;
|
||||
|
||||
cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
|
||||
if (!cfg)
|
||||
return -ENOMEM;
|
||||
|
||||
refin = pll_get_refin(pll);
|
||||
|
||||
mask = pmask(pll, PLL_PREDIV);
|
||||
index = pindex(pll, PLL_PREDIV);
|
||||
width = pwidth(pll, PLL_PREDIV);
|
||||
if (width && (sprd_pll_read(pll, index) & mask))
|
||||
refin = refin * 2;
|
||||
|
||||
mask = pmask(pll, PLL_POSTDIV);
|
||||
index = pindex(pll, PLL_POSTDIV);
|
||||
width = pwidth(pll, PLL_POSTDIV);
|
||||
cfg[index].msk = mask;
|
||||
if (width && ((pll->fflag == 1 && fvco <= pll->fvco) ||
|
||||
(pll->fflag == 0 && fvco > pll->fvco)))
|
||||
cfg[index].val |= mask;
|
||||
|
||||
if (width && fvco <= pll->fvco)
|
||||
fvco = fvco * 2;
|
||||
|
||||
mask = pmask(pll, PLL_DIV_S);
|
||||
index = pindex(pll, PLL_DIV_S);
|
||||
cfg[index].val |= mask;
|
||||
cfg[index].msk |= mask;
|
||||
|
||||
mask = pmask(pll, PLL_SDM_EN);
|
||||
index = pindex(pll, PLL_SDM_EN);
|
||||
cfg[index].val |= mask;
|
||||
cfg[index].msk |= mask;
|
||||
|
||||
nint = do_div(fvco, refin * CLK_PLL_1M);
|
||||
mask = pmask(pll, PLL_NINT);
|
||||
index = pindex(pll, PLL_NINT);
|
||||
shift = pshift(pll, PLL_NINT);
|
||||
cfg[index].val |= (nint << shift) & mask;
|
||||
cfg[index].msk |= mask;
|
||||
|
||||
mask = pmask(pll, PLL_KINT);
|
||||
index = pindex(pll, PLL_KINT);
|
||||
width = pwidth(pll, PLL_KINT);
|
||||
shift = pshift(pll, PLL_KINT);
|
||||
tmp = fvco - refin * nint * CLK_PLL_1M;
|
||||
tmp = do_div(tmp, 10000) * ((mask >> shift) + 1);
|
||||
kint = DIV_ROUND_CLOSEST_ULL(tmp, refin * 100);
|
||||
cfg[index].val |= (kint << shift) & mask;
|
||||
cfg[index].msk |= mask;
|
||||
|
||||
ibias_val = pll_get_ibias(fvco, pll->itable);
|
||||
|
||||
mask = pmask(pll, PLL_IBIAS);
|
||||
index = pindex(pll, PLL_IBIAS);
|
||||
shift = pshift(pll, PLL_IBIAS);
|
||||
cfg[index].val |= ibias_val << shift & mask;
|
||||
cfg[index].msk |= mask;
|
||||
|
||||
for (i = 0; i < regs_num; i++) {
|
||||
if (cfg[i].msk) {
|
||||
sprd_pll_write(pll, i, cfg[i].msk, cfg[i].val);
|
||||
ret |= SPRD_PLL_WRITE_CHECK(pll, i, cfg[i].msk,
|
||||
cfg[i].val);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
udelay(pll->udelay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long sprd_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sprd_pll *pll = hw_to_sprd_pll(hw);
|
||||
|
||||
return _sprd_pll_recalc_rate(pll, parent_rate);
|
||||
}
|
||||
|
||||
static int sprd_pll_set_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sprd_pll *pll = hw_to_sprd_pll(hw);
|
||||
|
||||
return _sprd_pll_set_rate(pll, rate, parent_rate);
|
||||
}
|
||||
|
||||
static int sprd_pll_clk_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_pll *pll = hw_to_sprd_pll(hw);
|
||||
|
||||
udelay(pll->udelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long sprd_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
|
||||
const struct clk_ops sprd_pll_ops = {
|
||||
.prepare = sprd_pll_clk_prepare,
|
||||
.recalc_rate = sprd_pll_recalc_rate,
|
||||
.round_rate = sprd_pll_round_rate,
|
||||
.set_rate = sprd_pll_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sprd_pll_ops);
|
108
drivers/clk/sprd/pll.h
Normal file
108
drivers/clk/sprd/pll.h
Normal file
@ -0,0 +1,108 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Spreadtrum pll clock driver
|
||||
//
|
||||
// Copyright (C) 2015~2017 Spreadtrum, Inc.
|
||||
// Author: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
|
||||
|
||||
#ifndef _SPRD_PLL_H_
|
||||
#define _SPRD_PLL_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct reg_cfg {
|
||||
u32 val;
|
||||
u32 msk;
|
||||
};
|
||||
|
||||
struct clk_bit_field {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
};
|
||||
|
||||
enum {
|
||||
PLL_LOCK_DONE,
|
||||
PLL_DIV_S,
|
||||
PLL_MOD_EN,
|
||||
PLL_SDM_EN,
|
||||
PLL_REFIN,
|
||||
PLL_IBIAS,
|
||||
PLL_N,
|
||||
PLL_NINT,
|
||||
PLL_KINT,
|
||||
PLL_PREDIV,
|
||||
PLL_POSTDIV,
|
||||
|
||||
PLL_FACT_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* struct sprd_pll - definition of adjustable pll clock
|
||||
*
|
||||
* @reg: registers used to set the configuration of pll clock,
|
||||
* reg[0] shows how many registers this pll clock uses.
|
||||
* @itable: pll ibias table, itable[0] means how many items this
|
||||
* table includes
|
||||
* @udelay delay time after setting rate
|
||||
* @factors used to calculate the pll clock rate
|
||||
* @fvco: fvco threshold rate
|
||||
* @fflag: fvco flag
|
||||
*/
|
||||
struct sprd_pll {
|
||||
u32 regs_num;
|
||||
const u64 *itable;
|
||||
const struct clk_bit_field *factors;
|
||||
u16 udelay;
|
||||
u16 k1;
|
||||
u16 k2;
|
||||
u16 fflag;
|
||||
u64 fvco;
|
||||
|
||||
struct sprd_clk_common common;
|
||||
};
|
||||
|
||||
#define SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \
|
||||
_regs_num, _itable, _factors, \
|
||||
_udelay, _k1, _k2, _fflag, _fvco) \
|
||||
struct sprd_pll _struct = { \
|
||||
.regs_num = _regs_num, \
|
||||
.itable = _itable, \
|
||||
.factors = _factors, \
|
||||
.udelay = _udelay, \
|
||||
.k1 = _k1, \
|
||||
.k2 = _k2, \
|
||||
.fflag = _fflag, \
|
||||
.fvco = _fvco, \
|
||||
.common = { \
|
||||
.regmap = NULL, \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&sprd_pll_ops, \
|
||||
0), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPRD_PLL_WITH_ITABLE_K(_struct, _name, _parent, _reg, \
|
||||
_regs_num, _itable, _factors, \
|
||||
_udelay, _k1, _k2) \
|
||||
SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \
|
||||
_regs_num, _itable, _factors, \
|
||||
_udelay, _k1, _k2, 0, 0)
|
||||
|
||||
#define SPRD_PLL_WITH_ITABLE_1K(_struct, _name, _parent, _reg, \
|
||||
_regs_num, _itable, _factors, _udelay) \
|
||||
SPRD_PLL_WITH_ITABLE_K_FVCO(_struct, _name, _parent, _reg, \
|
||||
_regs_num, _itable, _factors, \
|
||||
_udelay, 1000, 1000, 0, 0)
|
||||
|
||||
static inline struct sprd_pll *hw_to_sprd_pll(struct clk_hw *hw)
|
||||
{
|
||||
struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
|
||||
|
||||
return container_of(common, struct sprd_pll, common);
|
||||
}
|
||||
|
||||
extern const struct clk_ops sprd_pll_ops;
|
||||
|
||||
#endif /* _SPRD_PLL_H_ */
|
1974
drivers/clk/sprd/sc9860-clk.c
Normal file
1974
drivers/clk/sprd/sc9860-clk.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,35 +31,6 @@
|
||||
|
||||
struct device_node;
|
||||
|
||||
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
|
||||
&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = (const char *[]) { _parent }, \
|
||||
.num_parents = 1, \
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
|
||||
&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
#define CLK_FIXED_FACTOR(_struct, _name, _parent, \
|
||||
_div, _mult, _flags) \
|
||||
struct clk_fixed_factor _struct = { \
|
||||
.div = _div, \
|
||||
.mult = _mult, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&clk_fixed_factor_ops, \
|
||||
_flags), \
|
||||
}
|
||||
|
||||
struct ccu_common {
|
||||
void __iomem *base;
|
||||
u16 reg;
|
||||
|
@ -14,24 +14,6 @@
|
||||
|
||||
#define PNAME(x) static const char *x[]
|
||||
|
||||
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
|
||||
&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = (const char *[]) { _parent }, \
|
||||
.num_parents = 1, \
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
|
||||
&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
struct zx_pll_config {
|
||||
unsigned long rate;
|
||||
u32 cfg0;
|
||||
|
@ -58,6 +58,186 @@
|
||||
#define GCC_QPIC_AHB_CLK 41
|
||||
#define GCC_QPIC_CLK 42
|
||||
#define PCNOC_BFDCD_CLK_SRC 43
|
||||
#define GPLL2_MAIN 44
|
||||
#define GPLL2 45
|
||||
#define GPLL4_MAIN 46
|
||||
#define GPLL4 47
|
||||
#define GPLL6_MAIN 48
|
||||
#define GPLL6 49
|
||||
#define UBI32_PLL_MAIN 50
|
||||
#define UBI32_PLL 51
|
||||
#define NSS_CRYPTO_PLL_MAIN 52
|
||||
#define NSS_CRYPTO_PLL 53
|
||||
#define PCIE0_AXI_CLK_SRC 54
|
||||
#define PCIE0_AUX_CLK_SRC 55
|
||||
#define PCIE0_PIPE_CLK_SRC 56
|
||||
#define PCIE1_AXI_CLK_SRC 57
|
||||
#define PCIE1_AUX_CLK_SRC 58
|
||||
#define PCIE1_PIPE_CLK_SRC 59
|
||||
#define SDCC1_APPS_CLK_SRC 60
|
||||
#define SDCC1_ICE_CORE_CLK_SRC 61
|
||||
#define SDCC2_APPS_CLK_SRC 62
|
||||
#define USB0_MASTER_CLK_SRC 63
|
||||
#define USB0_AUX_CLK_SRC 64
|
||||
#define USB0_MOCK_UTMI_CLK_SRC 65
|
||||
#define USB0_PIPE_CLK_SRC 66
|
||||
#define USB1_MASTER_CLK_SRC 67
|
||||
#define USB1_AUX_CLK_SRC 68
|
||||
#define USB1_MOCK_UTMI_CLK_SRC 69
|
||||
#define USB1_PIPE_CLK_SRC 70
|
||||
#define GCC_XO_CLK_SRC 71
|
||||
#define SYSTEM_NOC_BFDCD_CLK_SRC 72
|
||||
#define NSS_CE_CLK_SRC 73
|
||||
#define NSS_NOC_BFDCD_CLK_SRC 74
|
||||
#define NSS_CRYPTO_CLK_SRC 75
|
||||
#define NSS_UBI0_CLK_SRC 76
|
||||
#define NSS_UBI0_DIV_CLK_SRC 77
|
||||
#define NSS_UBI1_CLK_SRC 78
|
||||
#define NSS_UBI1_DIV_CLK_SRC 79
|
||||
#define UBI_MPT_CLK_SRC 80
|
||||
#define NSS_IMEM_CLK_SRC 81
|
||||
#define NSS_PPE_CLK_SRC 82
|
||||
#define NSS_PORT1_RX_CLK_SRC 83
|
||||
#define NSS_PORT1_RX_DIV_CLK_SRC 84
|
||||
#define NSS_PORT1_TX_CLK_SRC 85
|
||||
#define NSS_PORT1_TX_DIV_CLK_SRC 86
|
||||
#define NSS_PORT2_RX_CLK_SRC 87
|
||||
#define NSS_PORT2_RX_DIV_CLK_SRC 88
|
||||
#define NSS_PORT2_TX_CLK_SRC 89
|
||||
#define NSS_PORT2_TX_DIV_CLK_SRC 90
|
||||
#define NSS_PORT3_RX_CLK_SRC 91
|
||||
#define NSS_PORT3_RX_DIV_CLK_SRC 92
|
||||
#define NSS_PORT3_TX_CLK_SRC 93
|
||||
#define NSS_PORT3_TX_DIV_CLK_SRC 94
|
||||
#define NSS_PORT4_RX_CLK_SRC 95
|
||||
#define NSS_PORT4_RX_DIV_CLK_SRC 96
|
||||
#define NSS_PORT4_TX_CLK_SRC 97
|
||||
#define NSS_PORT4_TX_DIV_CLK_SRC 98
|
||||
#define NSS_PORT5_RX_CLK_SRC 99
|
||||
#define NSS_PORT5_RX_DIV_CLK_SRC 100
|
||||
#define NSS_PORT5_TX_CLK_SRC 101
|
||||
#define NSS_PORT5_TX_DIV_CLK_SRC 102
|
||||
#define NSS_PORT6_RX_CLK_SRC 103
|
||||
#define NSS_PORT6_RX_DIV_CLK_SRC 104
|
||||
#define NSS_PORT6_TX_CLK_SRC 105
|
||||
#define NSS_PORT6_TX_DIV_CLK_SRC 106
|
||||
#define CRYPTO_CLK_SRC 107
|
||||
#define GP1_CLK_SRC 108
|
||||
#define GP2_CLK_SRC 109
|
||||
#define GP3_CLK_SRC 110
|
||||
#define GCC_PCIE0_AHB_CLK 111
|
||||
#define GCC_PCIE0_AUX_CLK 112
|
||||
#define GCC_PCIE0_AXI_M_CLK 113
|
||||
#define GCC_PCIE0_AXI_S_CLK 114
|
||||
#define GCC_PCIE0_PIPE_CLK 115
|
||||
#define GCC_SYS_NOC_PCIE0_AXI_CLK 116
|
||||
#define GCC_PCIE1_AHB_CLK 117
|
||||
#define GCC_PCIE1_AUX_CLK 118
|
||||
#define GCC_PCIE1_AXI_M_CLK 119
|
||||
#define GCC_PCIE1_AXI_S_CLK 120
|
||||
#define GCC_PCIE1_PIPE_CLK 121
|
||||
#define GCC_SYS_NOC_PCIE1_AXI_CLK 122
|
||||
#define GCC_USB0_AUX_CLK 123
|
||||
#define GCC_SYS_NOC_USB0_AXI_CLK 124
|
||||
#define GCC_USB0_MASTER_CLK 125
|
||||
#define GCC_USB0_MOCK_UTMI_CLK 126
|
||||
#define GCC_USB0_PHY_CFG_AHB_CLK 127
|
||||
#define GCC_USB0_PIPE_CLK 128
|
||||
#define GCC_USB0_SLEEP_CLK 129
|
||||
#define GCC_USB1_AUX_CLK 130
|
||||
#define GCC_SYS_NOC_USB1_AXI_CLK 131
|
||||
#define GCC_USB1_MASTER_CLK 132
|
||||
#define GCC_USB1_MOCK_UTMI_CLK 133
|
||||
#define GCC_USB1_PHY_CFG_AHB_CLK 134
|
||||
#define GCC_USB1_PIPE_CLK 135
|
||||
#define GCC_USB1_SLEEP_CLK 136
|
||||
#define GCC_SDCC1_AHB_CLK 137
|
||||
#define GCC_SDCC1_APPS_CLK 138
|
||||
#define GCC_SDCC1_ICE_CORE_CLK 139
|
||||
#define GCC_SDCC2_AHB_CLK 140
|
||||
#define GCC_SDCC2_APPS_CLK 141
|
||||
#define GCC_MEM_NOC_NSS_AXI_CLK 142
|
||||
#define GCC_NSS_CE_APB_CLK 143
|
||||
#define GCC_NSS_CE_AXI_CLK 144
|
||||
#define GCC_NSS_CFG_CLK 145
|
||||
#define GCC_NSS_CRYPTO_CLK 146
|
||||
#define GCC_NSS_CSR_CLK 147
|
||||
#define GCC_NSS_EDMA_CFG_CLK 148
|
||||
#define GCC_NSS_EDMA_CLK 149
|
||||
#define GCC_NSS_IMEM_CLK 150
|
||||
#define GCC_NSS_NOC_CLK 151
|
||||
#define GCC_NSS_PPE_BTQ_CLK 152
|
||||
#define GCC_NSS_PPE_CFG_CLK 153
|
||||
#define GCC_NSS_PPE_CLK 154
|
||||
#define GCC_NSS_PPE_IPE_CLK 155
|
||||
#define GCC_NSS_PTP_REF_CLK 156
|
||||
#define GCC_NSSNOC_CE_APB_CLK 157
|
||||
#define GCC_NSSNOC_CE_AXI_CLK 158
|
||||
#define GCC_NSSNOC_CRYPTO_CLK 159
|
||||
#define GCC_NSSNOC_PPE_CFG_CLK 160
|
||||
#define GCC_NSSNOC_PPE_CLK 161
|
||||
#define GCC_NSSNOC_QOSGEN_REF_CLK 162
|
||||
#define GCC_NSSNOC_SNOC_CLK 163
|
||||
#define GCC_NSSNOC_TIMEOUT_REF_CLK 164
|
||||
#define GCC_NSSNOC_UBI0_AHB_CLK 165
|
||||
#define GCC_NSSNOC_UBI1_AHB_CLK 166
|
||||
#define GCC_UBI0_AHB_CLK 167
|
||||
#define GCC_UBI0_AXI_CLK 168
|
||||
#define GCC_UBI0_NC_AXI_CLK 169
|
||||
#define GCC_UBI0_CORE_CLK 170
|
||||
#define GCC_UBI0_MPT_CLK 171
|
||||
#define GCC_UBI1_AHB_CLK 172
|
||||
#define GCC_UBI1_AXI_CLK 173
|
||||
#define GCC_UBI1_NC_AXI_CLK 174
|
||||
#define GCC_UBI1_CORE_CLK 175
|
||||
#define GCC_UBI1_MPT_CLK 176
|
||||
#define GCC_CMN_12GPLL_AHB_CLK 177
|
||||
#define GCC_CMN_12GPLL_SYS_CLK 178
|
||||
#define GCC_MDIO_AHB_CLK 179
|
||||
#define GCC_UNIPHY0_AHB_CLK 180
|
||||
#define GCC_UNIPHY0_SYS_CLK 181
|
||||
#define GCC_UNIPHY1_AHB_CLK 182
|
||||
#define GCC_UNIPHY1_SYS_CLK 183
|
||||
#define GCC_UNIPHY2_AHB_CLK 184
|
||||
#define GCC_UNIPHY2_SYS_CLK 185
|
||||
#define GCC_NSS_PORT1_RX_CLK 186
|
||||
#define GCC_NSS_PORT1_TX_CLK 187
|
||||
#define GCC_NSS_PORT2_RX_CLK 188
|
||||
#define GCC_NSS_PORT2_TX_CLK 189
|
||||
#define GCC_NSS_PORT3_RX_CLK 190
|
||||
#define GCC_NSS_PORT3_TX_CLK 191
|
||||
#define GCC_NSS_PORT4_RX_CLK 192
|
||||
#define GCC_NSS_PORT4_TX_CLK 193
|
||||
#define GCC_NSS_PORT5_RX_CLK 194
|
||||
#define GCC_NSS_PORT5_TX_CLK 195
|
||||
#define GCC_NSS_PORT6_RX_CLK 196
|
||||
#define GCC_NSS_PORT6_TX_CLK 197
|
||||
#define GCC_PORT1_MAC_CLK 198
|
||||
#define GCC_PORT2_MAC_CLK 199
|
||||
#define GCC_PORT3_MAC_CLK 200
|
||||
#define GCC_PORT4_MAC_CLK 201
|
||||
#define GCC_PORT5_MAC_CLK 202
|
||||
#define GCC_PORT6_MAC_CLK 203
|
||||
#define GCC_UNIPHY0_PORT1_RX_CLK 204
|
||||
#define GCC_UNIPHY0_PORT1_TX_CLK 205
|
||||
#define GCC_UNIPHY0_PORT2_RX_CLK 206
|
||||
#define GCC_UNIPHY0_PORT2_TX_CLK 207
|
||||
#define GCC_UNIPHY0_PORT3_RX_CLK 208
|
||||
#define GCC_UNIPHY0_PORT3_TX_CLK 209
|
||||
#define GCC_UNIPHY0_PORT4_RX_CLK 210
|
||||
#define GCC_UNIPHY0_PORT4_TX_CLK 211
|
||||
#define GCC_UNIPHY0_PORT5_RX_CLK 212
|
||||
#define GCC_UNIPHY0_PORT5_TX_CLK 213
|
||||
#define GCC_UNIPHY1_PORT5_RX_CLK 214
|
||||
#define GCC_UNIPHY1_PORT5_TX_CLK 215
|
||||
#define GCC_UNIPHY2_PORT6_RX_CLK 216
|
||||
#define GCC_UNIPHY2_PORT6_TX_CLK 217
|
||||
#define GCC_CRYPTO_AHB_CLK 218
|
||||
#define GCC_CRYPTO_AXI_CLK 219
|
||||
#define GCC_CRYPTO_CLK 220
|
||||
#define GCC_GP1_CLK 221
|
||||
#define GCC_GP2_CLK 222
|
||||
#define GCC_GP3_CLK 223
|
||||
|
||||
#define GCC_BLSP1_BCR 0
|
||||
#define GCC_BLSP1_QUP1_BCR 1
|
||||
@ -148,5 +328,47 @@
|
||||
#define GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR 86
|
||||
#define GCC_APC1_VOLTAGE_DROOP_DETECTOR_BCR 87
|
||||
#define GCC_SMMU_CATS_BCR 88
|
||||
#define GCC_UBI0_AXI_ARES 89
|
||||
#define GCC_UBI0_AHB_ARES 90
|
||||
#define GCC_UBI0_NC_AXI_ARES 91
|
||||
#define GCC_UBI0_DBG_ARES 92
|
||||
#define GCC_UBI0_CORE_CLAMP_ENABLE 93
|
||||
#define GCC_UBI0_CLKRST_CLAMP_ENABLE 94
|
||||
#define GCC_UBI1_AXI_ARES 95
|
||||
#define GCC_UBI1_AHB_ARES 96
|
||||
#define GCC_UBI1_NC_AXI_ARES 97
|
||||
#define GCC_UBI1_DBG_ARES 98
|
||||
#define GCC_UBI1_CORE_CLAMP_ENABLE 99
|
||||
#define GCC_UBI1_CLKRST_CLAMP_ENABLE 100
|
||||
#define GCC_NSS_CFG_ARES 101
|
||||
#define GCC_NSS_IMEM_ARES 102
|
||||
#define GCC_NSS_NOC_ARES 103
|
||||
#define GCC_NSS_CRYPTO_ARES 104
|
||||
#define GCC_NSS_CSR_ARES 105
|
||||
#define GCC_NSS_CE_APB_ARES 106
|
||||
#define GCC_NSS_CE_AXI_ARES 107
|
||||
#define GCC_NSSNOC_CE_APB_ARES 108
|
||||
#define GCC_NSSNOC_CE_AXI_ARES 109
|
||||
#define GCC_NSSNOC_UBI0_AHB_ARES 110
|
||||
#define GCC_NSSNOC_UBI1_AHB_ARES 111
|
||||
#define GCC_NSSNOC_SNOC_ARES 112
|
||||
#define GCC_NSSNOC_CRYPTO_ARES 113
|
||||
#define GCC_NSSNOC_ATB_ARES 114
|
||||
#define GCC_NSSNOC_QOSGEN_REF_ARES 115
|
||||
#define GCC_NSSNOC_TIMEOUT_REF_ARES 116
|
||||
#define GCC_PCIE0_PIPE_ARES 117
|
||||
#define GCC_PCIE0_SLEEP_ARES 118
|
||||
#define GCC_PCIE0_CORE_STICKY_ARES 119
|
||||
#define GCC_PCIE0_AXI_MASTER_ARES 120
|
||||
#define GCC_PCIE0_AXI_SLAVE_ARES 121
|
||||
#define GCC_PCIE0_AHB_ARES 122
|
||||
#define GCC_PCIE0_AXI_MASTER_STICKY_ARES 123
|
||||
#define GCC_PCIE1_PIPE_ARES 124
|
||||
#define GCC_PCIE1_SLEEP_ARES 125
|
||||
#define GCC_PCIE1_CORE_STICKY_ARES 126
|
||||
#define GCC_PCIE1_AXI_MASTER_ARES 127
|
||||
#define GCC_PCIE1_AXI_SLAVE_ARES 128
|
||||
#define GCC_PCIE1_AHB_ARES 129
|
||||
#define GCC_PCIE1_AXI_MASTER_STICKY_ARES 130
|
||||
|
||||
#endif
|
||||
|
404
include/dt-bindings/clock/sprd,sc9860-clk.h
Normal file
404
include/dt-bindings/clock/sprd,sc9860-clk.h
Normal file
@ -0,0 +1,404 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
//
|
||||
// Spreadtrum SC9860 platform clocks
|
||||
//
|
||||
// Copyright (C) 2017, Spreadtrum Communications Inc.
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_SC9860_H_
|
||||
#define _DT_BINDINGS_CLK_SC9860_H_
|
||||
|
||||
#define CLK_FAC_4M 0
|
||||
#define CLK_FAC_2M 1
|
||||
#define CLK_FAC_1M 2
|
||||
#define CLK_FAC_250K 3
|
||||
#define CLK_FAC_RPLL0_26M 4
|
||||
#define CLK_FAC_RPLL1_26M 5
|
||||
#define CLK_FAC_RCO25M 6
|
||||
#define CLK_FAC_RCO4M 7
|
||||
#define CLK_FAC_RCO2M 8
|
||||
#define CLK_FAC_3K2 9
|
||||
#define CLK_FAC_1K 10
|
||||
#define CLK_MPLL0_GATE 11
|
||||
#define CLK_MPLL1_GATE 12
|
||||
#define CLK_DPLL0_GATE 13
|
||||
#define CLK_DPLL1_GATE 14
|
||||
#define CLK_LTEPLL0_GATE 15
|
||||
#define CLK_TWPLL_GATE 16
|
||||
#define CLK_LTEPLL1_GATE 17
|
||||
#define CLK_RPLL0_GATE 18
|
||||
#define CLK_RPLL1_GATE 19
|
||||
#define CLK_CPPLL_GATE 20
|
||||
#define CLK_GPLL_GATE 21
|
||||
#define CLK_PMU_GATE_NUM (CLK_GPLL_GATE + 1)
|
||||
|
||||
#define CLK_MPLL0 0
|
||||
#define CLK_MPLL1 1
|
||||
#define CLK_DPLL0 2
|
||||
#define CLK_DPLL1 3
|
||||
#define CLK_RPLL0 4
|
||||
#define CLK_RPLL1 5
|
||||
#define CLK_TWPLL 6
|
||||
#define CLK_LTEPLL0 7
|
||||
#define CLK_LTEPLL1 8
|
||||
#define CLK_GPLL 9
|
||||
#define CLK_CPPLL 10
|
||||
#define CLK_GPLL_42M5 11
|
||||
#define CLK_TWPLL_768M 12
|
||||
#define CLK_TWPLL_384M 13
|
||||
#define CLK_TWPLL_192M 14
|
||||
#define CLK_TWPLL_96M 15
|
||||
#define CLK_TWPLL_48M 16
|
||||
#define CLK_TWPLL_24M 17
|
||||
#define CLK_TWPLL_12M 18
|
||||
#define CLK_TWPLL_512M 19
|
||||
#define CLK_TWPLL_256M 20
|
||||
#define CLK_TWPLL_128M 21
|
||||
#define CLK_TWPLL_64M 22
|
||||
#define CLK_TWPLL_307M2 23
|
||||
#define CLK_TWPLL_153M6 24
|
||||
#define CLK_TWPLL_76M8 25
|
||||
#define CLK_TWPLL_51M2 26
|
||||
#define CLK_TWPLL_38M4 27
|
||||
#define CLK_TWPLL_19M2 28
|
||||
#define CLK_L0_614M4 29
|
||||
#define CLK_L0_409M6 30
|
||||
#define CLK_L0_38M 31
|
||||
#define CLK_L1_38M 32
|
||||
#define CLK_RPLL0_192M 33
|
||||
#define CLK_RPLL0_96M 34
|
||||
#define CLK_RPLL0_48M 35
|
||||
#define CLK_RPLL1_468M 36
|
||||
#define CLK_RPLL1_192M 37
|
||||
#define CLK_RPLL1_96M 38
|
||||
#define CLK_RPLL1_64M 39
|
||||
#define CLK_RPLL1_48M 40
|
||||
#define CLK_DPLL0_50M 41
|
||||
#define CLK_DPLL1_50M 42
|
||||
#define CLK_CPPLL_50M 43
|
||||
#define CLK_M0_39M 44
|
||||
#define CLK_M1_63M 45
|
||||
#define CLK_PLL_NUM (CLK_M1_63M + 1)
|
||||
|
||||
|
||||
#define CLK_AP_APB 0
|
||||
#define CLK_AP_USB3 1
|
||||
#define CLK_UART0 2
|
||||
#define CLK_UART1 3
|
||||
#define CLK_UART2 4
|
||||
#define CLK_UART3 5
|
||||
#define CLK_UART4 6
|
||||
#define CLK_I2C0 7
|
||||
#define CLK_I2C1 8
|
||||
#define CLK_I2C2 9
|
||||
#define CLK_I2C3 10
|
||||
#define CLK_I2C4 11
|
||||
#define CLK_I2C5 12
|
||||
#define CLK_SPI0 13
|
||||
#define CLK_SPI1 14
|
||||
#define CLK_SPI2 15
|
||||
#define CLK_SPI3 16
|
||||
#define CLK_IIS0 17
|
||||
#define CLK_IIS1 18
|
||||
#define CLK_IIS2 19
|
||||
#define CLK_IIS3 20
|
||||
#define CLK_AP_CLK_NUM (CLK_IIS3 + 1)
|
||||
|
||||
#define CLK_AON_APB 0
|
||||
#define CLK_AUX0 1
|
||||
#define CLK_AUX1 2
|
||||
#define CLK_AUX2 3
|
||||
#define CLK_PROBE 4
|
||||
#define CLK_SP_AHB 5
|
||||
#define CLK_CCI 6
|
||||
#define CLK_GIC 7
|
||||
#define CLK_CSSYS 8
|
||||
#define CLK_SDIO0_2X 9
|
||||
#define CLK_SDIO1_2X 10
|
||||
#define CLK_SDIO2_2X 11
|
||||
#define CLK_EMMC_2X 12
|
||||
#define CLK_SDIO0_1X 13
|
||||
#define CLK_SDIO1_1X 14
|
||||
#define CLK_SDIO2_1X 15
|
||||
#define CLK_EMMC_1X 16
|
||||
#define CLK_ADI 17
|
||||
#define CLK_PWM0 18
|
||||
#define CLK_PWM1 19
|
||||
#define CLK_PWM2 20
|
||||
#define CLK_PWM3 21
|
||||
#define CLK_EFUSE 22
|
||||
#define CLK_CM3_UART0 23
|
||||
#define CLK_CM3_UART1 24
|
||||
#define CLK_THM 25
|
||||
#define CLK_CM3_I2C0 26
|
||||
#define CLK_CM3_I2C1 27
|
||||
#define CLK_CM4_SPI 28
|
||||
#define CLK_AON_I2C 29
|
||||
#define CLK_AVS 30
|
||||
#define CLK_CA53_DAP 31
|
||||
#define CLK_CA53_TS 32
|
||||
#define CLK_DJTAG_TCK 33
|
||||
#define CLK_PMU 34
|
||||
#define CLK_PMU_26M 35
|
||||
#define CLK_DEBOUNCE 36
|
||||
#define CLK_OTG2_REF 37
|
||||
#define CLK_USB3_REF 38
|
||||
#define CLK_AP_AXI 39
|
||||
#define CLK_AON_PREDIV_NUM (CLK_AP_AXI + 1)
|
||||
|
||||
#define CLK_USB3_EB 0
|
||||
#define CLK_USB3_SUSPEND_EB 1
|
||||
#define CLK_USB3_REF_EB 2
|
||||
#define CLK_DMA_EB 3
|
||||
#define CLK_SDIO0_EB 4
|
||||
#define CLK_SDIO1_EB 5
|
||||
#define CLK_SDIO2_EB 6
|
||||
#define CLK_EMMC_EB 7
|
||||
#define CLK_ROM_EB 8
|
||||
#define CLK_BUSMON_EB 9
|
||||
#define CLK_CC63S_EB 10
|
||||
#define CLK_CC63P_EB 11
|
||||
#define CLK_CE0_EB 12
|
||||
#define CLK_CE1_EB 13
|
||||
#define CLK_APAHB_GATE_NUM (CLK_CE1_EB + 1)
|
||||
|
||||
#define CLK_AVS_LIT_EB 0
|
||||
#define CLK_AVS_BIG_EB 1
|
||||
#define CLK_AP_INTC5_EB 2
|
||||
#define CLK_GPIO_EB 3
|
||||
#define CLK_PWM0_EB 4
|
||||
#define CLK_PWM1_EB 5
|
||||
#define CLK_PWM2_EB 6
|
||||
#define CLK_PWM3_EB 7
|
||||
#define CLK_KPD_EB 8
|
||||
#define CLK_AON_SYS_EB 9
|
||||
#define CLK_AP_SYS_EB 10
|
||||
#define CLK_AON_TMR_EB 11
|
||||
#define CLK_AP_TMR0_EB 12
|
||||
#define CLK_EFUSE_EB 13
|
||||
#define CLK_EIC_EB 14
|
||||
#define CLK_PUB1_REG_EB 15
|
||||
#define CLK_ADI_EB 16
|
||||
#define CLK_AP_INTC0_EB 17
|
||||
#define CLK_AP_INTC1_EB 18
|
||||
#define CLK_AP_INTC2_EB 19
|
||||
#define CLK_AP_INTC3_EB 20
|
||||
#define CLK_AP_INTC4_EB 21
|
||||
#define CLK_SPLK_EB 22
|
||||
#define CLK_MSPI_EB 23
|
||||
#define CLK_PUB0_REG_EB 24
|
||||
#define CLK_PIN_EB 25
|
||||
#define CLK_AON_CKG_EB 26
|
||||
#define CLK_GPU_EB 27
|
||||
#define CLK_APCPU_TS0_EB 28
|
||||
#define CLK_APCPU_TS1_EB 29
|
||||
#define CLK_DAP_EB 30
|
||||
#define CLK_I2C_EB 31
|
||||
#define CLK_PMU_EB 32
|
||||
#define CLK_THM_EB 33
|
||||
#define CLK_AUX0_EB 34
|
||||
#define CLK_AUX1_EB 35
|
||||
#define CLK_AUX2_EB 36
|
||||
#define CLK_PROBE_EB 37
|
||||
#define CLK_GPU0_AVS_EB 38
|
||||
#define CLK_GPU1_AVS_EB 39
|
||||
#define CLK_APCPU_WDG_EB 40
|
||||
#define CLK_AP_TMR1_EB 41
|
||||
#define CLK_AP_TMR2_EB 42
|
||||
#define CLK_DISP_EMC_EB 43
|
||||
#define CLK_ZIP_EMC_EB 44
|
||||
#define CLK_GSP_EMC_EB 45
|
||||
#define CLK_OSC_AON_EB 46
|
||||
#define CLK_LVDS_TRX_EB 47
|
||||
#define CLK_LVDS_TCXO_EB 48
|
||||
#define CLK_MDAR_EB 49
|
||||
#define CLK_RTC4M0_CAL_EB 50
|
||||
#define CLK_RCT100M_CAL_EB 51
|
||||
#define CLK_DJTAG_EB 52
|
||||
#define CLK_MBOX_EB 53
|
||||
#define CLK_AON_DMA_EB 54
|
||||
#define CLK_DBG_EMC_EB 55
|
||||
#define CLK_LVDS_PLL_DIV_EN 56
|
||||
#define CLK_DEF_EB 57
|
||||
#define CLK_AON_APB_RSV0 58
|
||||
#define CLK_ORP_JTAG_EB 59
|
||||
#define CLK_VSP_EB 60
|
||||
#define CLK_CAM_EB 61
|
||||
#define CLK_DISP_EB 62
|
||||
#define CLK_DBG_AXI_IF_EB 63
|
||||
#define CLK_SDIO0_2X_EN 64
|
||||
#define CLK_SDIO1_2X_EN 65
|
||||
#define CLK_SDIO2_2X_EN 66
|
||||
#define CLK_EMMC_2X_EN 67
|
||||
#define CLK_AON_GATE_NUM (CLK_EMMC_2X_EN + 1)
|
||||
|
||||
#define CLK_LIT_MCU 0
|
||||
#define CLK_BIG_MCU 1
|
||||
#define CLK_AONSECURE_NUM (CLK_BIG_MCU + 1)
|
||||
|
||||
#define CLK_AGCP_IIS0_EB 0
|
||||
#define CLK_AGCP_IIS1_EB 1
|
||||
#define CLK_AGCP_IIS2_EB 2
|
||||
#define CLK_AGCP_IIS3_EB 3
|
||||
#define CLK_AGCP_UART_EB 4
|
||||
#define CLK_AGCP_DMACP_EB 5
|
||||
#define CLK_AGCP_DMAAP_EB 6
|
||||
#define CLK_AGCP_ARC48K_EB 7
|
||||
#define CLK_AGCP_SRC44P1K_EB 8
|
||||
#define CLK_AGCP_MCDT_EB 9
|
||||
#define CLK_AGCP_VBCIFD_EB 10
|
||||
#define CLK_AGCP_VBC_EB 11
|
||||
#define CLK_AGCP_SPINLOCK_EB 12
|
||||
#define CLK_AGCP_ICU_EB 13
|
||||
#define CLK_AGCP_AP_ASHB_EB 14
|
||||
#define CLK_AGCP_CP_ASHB_EB 15
|
||||
#define CLK_AGCP_AUD_EB 16
|
||||
#define CLK_AGCP_AUDIF_EB 17
|
||||
#define CLK_AGCP_GATE_NUM (CLK_AGCP_AUDIF_EB + 1)
|
||||
|
||||
#define CLK_GPU 0
|
||||
#define CLK_GPU_NUM (CLK_GPU + 1)
|
||||
|
||||
#define CLK_AHB_VSP 0
|
||||
#define CLK_VSP 1
|
||||
#define CLK_VSP_ENC 2
|
||||
#define CLK_VPP 3
|
||||
#define CLK_VSP_26M 4
|
||||
#define CLK_VSP_NUM (CLK_VSP_26M + 1)
|
||||
|
||||
#define CLK_VSP_DEC_EB 0
|
||||
#define CLK_VSP_CKG_EB 1
|
||||
#define CLK_VSP_MMU_EB 2
|
||||
#define CLK_VSP_ENC_EB 3
|
||||
#define CLK_VPP_EB 4
|
||||
#define CLK_VSP_26M_EB 5
|
||||
#define CLK_VSP_AXI_GATE 6
|
||||
#define CLK_VSP_ENC_GATE 7
|
||||
#define CLK_VPP_AXI_GATE 8
|
||||
#define CLK_VSP_BM_GATE 9
|
||||
#define CLK_VSP_ENC_BM_GATE 10
|
||||
#define CLK_VPP_BM_GATE 11
|
||||
#define CLK_VSP_GATE_NUM (CLK_VPP_BM_GATE + 1)
|
||||
|
||||
#define CLK_AHB_CAM 0
|
||||
#define CLK_SENSOR0 1
|
||||
#define CLK_SENSOR1 2
|
||||
#define CLK_SENSOR2 3
|
||||
#define CLK_MIPI_CSI0_EB 4
|
||||
#define CLK_MIPI_CSI1_EB 5
|
||||
#define CLK_CAM_NUM (CLK_MIPI_CSI1_EB + 1)
|
||||
|
||||
#define CLK_DCAM0_EB 0
|
||||
#define CLK_DCAM1_EB 1
|
||||
#define CLK_ISP0_EB 2
|
||||
#define CLK_CSI0_EB 3
|
||||
#define CLK_CSI1_EB 4
|
||||
#define CLK_JPG0_EB 5
|
||||
#define CLK_JPG1_EB 6
|
||||
#define CLK_CAM_CKG_EB 7
|
||||
#define CLK_CAM_MMU_EB 8
|
||||
#define CLK_ISP1_EB 9
|
||||
#define CLK_CPP_EB 10
|
||||
#define CLK_MMU_PF_EB 11
|
||||
#define CLK_ISP2_EB 12
|
||||
#define CLK_DCAM2ISP_IF_EB 13
|
||||
#define CLK_ISP2DCAM_IF_EB 14
|
||||
#define CLK_ISP_LCLK_EB 15
|
||||
#define CLK_ISP_ICLK_EB 16
|
||||
#define CLK_ISP_MCLK_EB 17
|
||||
#define CLK_ISP_PCLK_EB 18
|
||||
#define CLK_ISP_ISP2DCAM_EB 19
|
||||
#define CLK_DCAM0_IF_EB 20
|
||||
#define CLK_CLK26M_IF_EB 21
|
||||
#define CLK_CPHY0_GATE 22
|
||||
#define CLK_MIPI_CSI0_GATE 23
|
||||
#define CLK_CPHY1_GATE 24
|
||||
#define CLK_MIPI_CSI1 25
|
||||
#define CLK_DCAM0_AXI_GATE 26
|
||||
#define CLK_DCAM1_AXI_GATE 27
|
||||
#define CLK_SENSOR0_GATE 28
|
||||
#define CLK_SENSOR1_GATE 29
|
||||
#define CLK_JPG0_AXI_GATE 30
|
||||
#define CLK_GPG1_AXI_GATE 31
|
||||
#define CLK_ISP0_AXI_GATE 32
|
||||
#define CLK_ISP1_AXI_GATE 33
|
||||
#define CLK_ISP2_AXI_GATE 34
|
||||
#define CLK_CPP_AXI_GATE 35
|
||||
#define CLK_D0_IF_AXI_GATE 36
|
||||
#define CLK_D2I_IF_AXI_GATE 37
|
||||
#define CLK_I2D_IF_AXI_GATE 38
|
||||
#define CLK_SPARE_AXI_GATE 39
|
||||
#define CLK_SENSOR2_GATE 40
|
||||
#define CLK_D0IF_IN_D_EN 41
|
||||
#define CLK_D1IF_IN_D_EN 42
|
||||
#define CLK_D0IF_IN_D2I_EN 43
|
||||
#define CLK_D1IF_IN_D2I_EN 44
|
||||
#define CLK_IA_IN_D2I_EN 45
|
||||
#define CLK_IB_IN_D2I_EN 46
|
||||
#define CLK_IC_IN_D2I_EN 47
|
||||
#define CLK_IA_IN_I_EN 48
|
||||
#define CLK_IB_IN_I_EN 49
|
||||
#define CLK_IC_IN_I_EN 50
|
||||
#define CLK_CAM_GATE_NUM (CLK_IC_IN_I_EN + 1)
|
||||
|
||||
#define CLK_AHB_DISP 0
|
||||
#define CLK_DISPC0_DPI 1
|
||||
#define CLK_DISPC1_DPI 2
|
||||
#define CLK_DISP_NUM (CLK_DISPC1_DPI + 1)
|
||||
|
||||
#define CLK_DISPC0_EB 0
|
||||
#define CLK_DISPC1_EB 1
|
||||
#define CLK_DISPC_MMU_EB 2
|
||||
#define CLK_GSP0_EB 3
|
||||
#define CLK_GSP1_EB 4
|
||||
#define CLK_GSP0_MMU_EB 5
|
||||
#define CLK_GSP1_MMU_EB 6
|
||||
#define CLK_DSI0_EB 7
|
||||
#define CLK_DSI1_EB 8
|
||||
#define CLK_DISP_CKG_EB 9
|
||||
#define CLK_DISP_GPU_EB 10
|
||||
#define CLK_GPU_MTX_EB 11
|
||||
#define CLK_GSP_MTX_EB 12
|
||||
#define CLK_TMC_MTX_EB 13
|
||||
#define CLK_DISPC_MTX_EB 14
|
||||
#define CLK_DPHY0_GATE 15
|
||||
#define CLK_DPHY1_GATE 16
|
||||
#define CLK_GSP0_A_GATE 17
|
||||
#define CLK_GSP1_A_GATE 18
|
||||
#define CLK_GSP0_F_GATE 19
|
||||
#define CLK_GSP1_F_GATE 20
|
||||
#define CLK_D_MTX_F_GATE 21
|
||||
#define CLK_D_MTX_A_GATE 22
|
||||
#define CLK_D_NOC_F_GATE 23
|
||||
#define CLK_D_NOC_A_GATE 24
|
||||
#define CLK_GSP_MTX_F_GATE 25
|
||||
#define CLK_GSP_MTX_A_GATE 26
|
||||
#define CLK_GSP_NOC_F_GATE 27
|
||||
#define CLK_GSP_NOC_A_GATE 28
|
||||
#define CLK_DISPM0IDLE_GATE 29
|
||||
#define CLK_GSPM0IDLE_GATE 30
|
||||
#define CLK_DISP_GATE_NUM (CLK_GSPM0IDLE_GATE + 1)
|
||||
|
||||
#define CLK_SIM0_EB 0
|
||||
#define CLK_IIS0_EB 1
|
||||
#define CLK_IIS1_EB 2
|
||||
#define CLK_IIS2_EB 3
|
||||
#define CLK_IIS3_EB 4
|
||||
#define CLK_SPI0_EB 5
|
||||
#define CLK_SPI1_EB 6
|
||||
#define CLK_SPI2_EB 7
|
||||
#define CLK_I2C0_EB 8
|
||||
#define CLK_I2C1_EB 9
|
||||
#define CLK_I2C2_EB 10
|
||||
#define CLK_I2C3_EB 11
|
||||
#define CLK_I2C4_EB 12
|
||||
#define CLK_I2C5_EB 13
|
||||
#define CLK_UART0_EB 14
|
||||
#define CLK_UART1_EB 15
|
||||
#define CLK_UART2_EB 16
|
||||
#define CLK_UART3_EB 17
|
||||
#define CLK_UART4_EB 18
|
||||
#define CLK_AP_CKG_EB 19
|
||||
#define CLK_SPI3_EB 20
|
||||
#define CLK_APAPB_GATE_NUM (CLK_SPI3_EB + 1)
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_SC9860_H_ */
|
@ -807,6 +807,44 @@ extern struct of_device_id __clk_of_table;
|
||||
} \
|
||||
OF_DECLARE_1(clk, name, compat, name##_of_clk_init_driver)
|
||||
|
||||
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
|
||||
(&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = (const char *[]) { _parent }, \
|
||||
.num_parents = 1, \
|
||||
.ops = _ops, \
|
||||
})
|
||||
|
||||
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
|
||||
(&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.ops = _ops, \
|
||||
})
|
||||
|
||||
#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
|
||||
(&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = NULL, \
|
||||
.num_parents = 0, \
|
||||
.ops = _ops, \
|
||||
})
|
||||
|
||||
#define CLK_FIXED_FACTOR(_struct, _name, _parent, \
|
||||
_div, _mult, _flags) \
|
||||
struct clk_fixed_factor _struct = { \
|
||||
.div = _div, \
|
||||
.mult = _mult, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&clk_fixed_factor_ops, \
|
||||
_flags), \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
int of_clk_add_provider(struct device_node *np,
|
||||
struct clk *(*clk_src_get)(struct of_phandle_args *args,
|
||||
|
Loading…
Reference in New Issue
Block a user