Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (C) 2018-2019 SiFive, Inc.
0004  * Wesley Terpstra
0005  * Paul Walmsley
0006  * Zong Li
0007  */
0008 
0009 #ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
0010 #define __SIFIVE_CLK_SIFIVE_PRCI_H
0011 
0012 #include <linux/clk/analogbits-wrpll-cln28hpc.h>
0013 #include <linux/clk-provider.h>
0014 #include <linux/reset/reset-simple.h>
0015 #include <linux/platform_device.h>
0016 
0017 /*
0018  * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
0019  *     hfclk and rtcclk
0020  */
0021 #define EXPECTED_CLK_PARENT_COUNT 2
0022 
0023 /*
0024  * Register offsets and bitmasks
0025  */
0026 
0027 /* COREPLLCFG0 */
0028 #define PRCI_COREPLLCFG0_OFFSET     0x4
0029 #define PRCI_COREPLLCFG0_DIVR_SHIFT 0
0030 #define PRCI_COREPLLCFG0_DIVR_MASK  (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
0031 #define PRCI_COREPLLCFG0_DIVF_SHIFT 6
0032 #define PRCI_COREPLLCFG0_DIVF_MASK  (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
0033 #define PRCI_COREPLLCFG0_DIVQ_SHIFT 15
0034 #define PRCI_COREPLLCFG0_DIVQ_MASK  (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
0035 #define PRCI_COREPLLCFG0_RANGE_SHIFT    18
0036 #define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
0037 #define PRCI_COREPLLCFG0_BYPASS_SHIFT   24
0038 #define PRCI_COREPLLCFG0_BYPASS_MASK    (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
0039 #define PRCI_COREPLLCFG0_FSE_SHIFT  25
0040 #define PRCI_COREPLLCFG0_FSE_MASK   (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
0041 #define PRCI_COREPLLCFG0_LOCK_SHIFT 31
0042 #define PRCI_COREPLLCFG0_LOCK_MASK  (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
0043 
0044 /* COREPLLCFG1 */
0045 #define PRCI_COREPLLCFG1_OFFSET     0x8
0046 #define PRCI_COREPLLCFG1_CKE_SHIFT  31
0047 #define PRCI_COREPLLCFG1_CKE_MASK   (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
0048 
0049 /* DDRPLLCFG0 */
0050 #define PRCI_DDRPLLCFG0_OFFSET      0xc
0051 #define PRCI_DDRPLLCFG0_DIVR_SHIFT  0
0052 #define PRCI_DDRPLLCFG0_DIVR_MASK   (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
0053 #define PRCI_DDRPLLCFG0_DIVF_SHIFT  6
0054 #define PRCI_DDRPLLCFG0_DIVF_MASK   (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
0055 #define PRCI_DDRPLLCFG0_DIVQ_SHIFT  15
0056 #define PRCI_DDRPLLCFG0_DIVQ_MASK   (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
0057 #define PRCI_DDRPLLCFG0_RANGE_SHIFT 18
0058 #define PRCI_DDRPLLCFG0_RANGE_MASK  (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
0059 #define PRCI_DDRPLLCFG0_BYPASS_SHIFT    24
0060 #define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
0061 #define PRCI_DDRPLLCFG0_FSE_SHIFT   25
0062 #define PRCI_DDRPLLCFG0_FSE_MASK    (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
0063 #define PRCI_DDRPLLCFG0_LOCK_SHIFT  31
0064 #define PRCI_DDRPLLCFG0_LOCK_MASK   (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
0065 
0066 /* DDRPLLCFG1 */
0067 #define PRCI_DDRPLLCFG1_OFFSET      0x10
0068 #define PRCI_DDRPLLCFG1_CKE_SHIFT   31
0069 #define PRCI_DDRPLLCFG1_CKE_MASK    (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
0070 
0071 /* PCIEAUX */
0072 #define PRCI_PCIE_AUX_OFFSET        0x14
0073 #define PRCI_PCIE_AUX_EN_SHIFT      0
0074 #define PRCI_PCIE_AUX_EN_MASK       (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
0075 
0076 /* GEMGXLPLLCFG0 */
0077 #define PRCI_GEMGXLPLLCFG0_OFFSET   0x1c
0078 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT   0
0079 #define PRCI_GEMGXLPLLCFG0_DIVR_MASK    (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
0080 #define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT   6
0081 #define PRCI_GEMGXLPLLCFG0_DIVF_MASK    (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
0082 #define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT   15
0083 #define PRCI_GEMGXLPLLCFG0_DIVQ_MASK    (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
0084 #define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT  18
0085 #define PRCI_GEMGXLPLLCFG0_RANGE_MASK   (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
0086 #define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24
0087 #define PRCI_GEMGXLPLLCFG0_BYPASS_MASK  (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
0088 #define PRCI_GEMGXLPLLCFG0_FSE_SHIFT    25
0089 #define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
0090 #define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT   31
0091 #define PRCI_GEMGXLPLLCFG0_LOCK_MASK    (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
0092 
0093 /* GEMGXLPLLCFG1 */
0094 #define PRCI_GEMGXLPLLCFG1_OFFSET   0x20
0095 #define PRCI_GEMGXLPLLCFG1_CKE_SHIFT    31
0096 #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
0097 
0098 /* CORECLKSEL */
0099 #define PRCI_CORECLKSEL_OFFSET          0x24
0100 #define PRCI_CORECLKSEL_CORECLKSEL_SHIFT    0
0101 #define PRCI_CORECLKSEL_CORECLKSEL_MASK                 \
0102         (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
0103 
0104 /* DEVICESRESETREG */
0105 #define PRCI_DEVICESRESETREG_OFFSET             0x28
0106 #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT       0
0107 #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK            \
0108         (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
0109 #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT        1
0110 #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK             \
0111         (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
0112 #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT        2
0113 #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK             \
0114         (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
0115 #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT        3
0116 #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK             \
0117         (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
0118 #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT         5
0119 #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK              \
0120         (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
0121 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT       6
0122 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK            \
0123         (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
0124 
0125 #define PRCI_RST_NR                     7
0126 
0127 /* CLKMUXSTATUSREG */
0128 #define PRCI_CLKMUXSTATUSREG_OFFSET             0x2c
0129 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT      1
0130 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK           \
0131         (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
0132 
0133 /* CLTXPLLCFG0 */
0134 #define PRCI_CLTXPLLCFG0_OFFSET     0x30
0135 #define PRCI_CLTXPLLCFG0_DIVR_SHIFT 0
0136 #define PRCI_CLTXPLLCFG0_DIVR_MASK  (0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT)
0137 #define PRCI_CLTXPLLCFG0_DIVF_SHIFT 6
0138 #define PRCI_CLTXPLLCFG0_DIVF_MASK  (0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT)
0139 #define PRCI_CLTXPLLCFG0_DIVQ_SHIFT 15
0140 #define PRCI_CLTXPLLCFG0_DIVQ_MASK  (0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT)
0141 #define PRCI_CLTXPLLCFG0_RANGE_SHIFT    18
0142 #define PRCI_CLTXPLLCFG0_RANGE_MASK (0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT)
0143 #define PRCI_CLTXPLLCFG0_BYPASS_SHIFT   24
0144 #define PRCI_CLTXPLLCFG0_BYPASS_MASK    (0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT)
0145 #define PRCI_CLTXPLLCFG0_FSE_SHIFT  25
0146 #define PRCI_CLTXPLLCFG0_FSE_MASK   (0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT)
0147 #define PRCI_CLTXPLLCFG0_LOCK_SHIFT 31
0148 #define PRCI_CLTXPLLCFG0_LOCK_MASK  (0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT)
0149 
0150 /* CLTXPLLCFG1 */
0151 #define PRCI_CLTXPLLCFG1_OFFSET     0x34
0152 #define PRCI_CLTXPLLCFG1_CKE_SHIFT  31
0153 #define PRCI_CLTXPLLCFG1_CKE_MASK   (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
0154 
0155 /* DVFSCOREPLLCFG0 */
0156 #define PRCI_DVFSCOREPLLCFG0_OFFSET 0x38
0157 
0158 /* DVFSCOREPLLCFG1 */
0159 #define PRCI_DVFSCOREPLLCFG1_OFFSET 0x3c
0160 #define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT  31
0161 #define PRCI_DVFSCOREPLLCFG1_CKE_MASK   (0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT)
0162 
0163 /* COREPLLSEL */
0164 #define PRCI_COREPLLSEL_OFFSET          0x40
0165 #define PRCI_COREPLLSEL_COREPLLSEL_SHIFT    0
0166 #define PRCI_COREPLLSEL_COREPLLSEL_MASK                 \
0167         (0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT)
0168 
0169 /* HFPCLKPLLCFG0 */
0170 #define PRCI_HFPCLKPLLCFG0_OFFSET       0x50
0171 #define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT      0
0172 #define PRCI_HFPCLKPLL_CFG0_DIVR_MASK                   \
0173         (0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT)
0174 #define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT      6
0175 #define PRCI_HFPCLKPLL_CFG0_DIVF_MASK                   \
0176         (0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT)
0177 #define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT      15
0178 #define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK                   \
0179         (0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT)
0180 #define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT     18
0181 #define PRCI_HFPCLKPLL_CFG0_RANGE_MASK                  \
0182         (0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT)
0183 #define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT    24
0184 #define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK                 \
0185         (0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT)
0186 #define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT       25
0187 #define PRCI_HFPCLKPLL_CFG0_FSE_MASK                    \
0188         (0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT)
0189 #define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT      31
0190 #define PRCI_HFPCLKPLL_CFG0_LOCK_MASK                   \
0191         (0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT)
0192 
0193 /* HFPCLKPLLCFG1 */
0194 #define PRCI_HFPCLKPLLCFG1_OFFSET       0x54
0195 #define PRCI_HFPCLKPLLCFG1_CKE_SHIFT        31
0196 #define PRCI_HFPCLKPLLCFG1_CKE_MASK                 \
0197         (0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT)
0198 
0199 /* HFPCLKPLLSEL */
0200 #define PRCI_HFPCLKPLLSEL_OFFSET        0x58
0201 #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT    0
0202 #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK             \
0203         (0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT)
0204 
0205 /* HFPCLKPLLDIV */
0206 #define PRCI_HFPCLKPLLDIV_OFFSET        0x5c
0207 
0208 /* PRCIPLL */
0209 #define PRCI_PRCIPLL_OFFSET         0xe0
0210 
0211 /* PROCMONCFG */
0212 #define PRCI_PROCMONCFG_OFFSET          0xf0
0213 
0214 /*
0215  * Private structures
0216  */
0217 
0218 /**
0219  * struct __prci_data - per-device-instance data
0220  * @va: base virtual address of the PRCI IP block
0221  * @hw_clks: encapsulates struct clk_hw records
0222  *
0223  * PRCI per-device instance data
0224  */
0225 struct __prci_data {
0226     void __iomem *va;
0227     struct reset_simple_data reset;
0228     struct clk_hw_onecell_data hw_clks;
0229 };
0230 
0231 /**
0232  * struct __prci_wrpll_data - WRPLL configuration and integration data
0233  * @c: WRPLL current configuration record
0234  * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
0235  * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
0236  * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
0237  * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
0238  *
0239  * @enable_bypass and @disable_bypass are used for WRPLL instances
0240  * that contain a separate external glitchless clock mux downstream
0241  * from the PLL.  The WRPLL internal bypass mux is not glitchless.
0242  */
0243 struct __prci_wrpll_data {
0244     struct wrpll_cfg c;
0245     void (*enable_bypass)(struct __prci_data *pd);
0246     void (*disable_bypass)(struct __prci_data *pd);
0247     u8 cfg0_offs;
0248     u8 cfg1_offs;
0249 };
0250 
0251 /**
0252  * struct __prci_clock - describes a clock device managed by PRCI
0253  * @name: user-readable clock name string - should match the manual
0254  * @parent_name: parent name for this clock
0255  * @ops: struct clk_ops for the Linux clock framework to use for control
0256  * @hw: Linux-private clock data
0257  * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
0258  * @pd: PRCI-specific data associated with this clock (if not NULL)
0259  *
0260  * PRCI clock data.  Used by the PRCI driver to register PRCI-provided
0261  * clocks to the Linux clock infrastructure.
0262  */
0263 struct __prci_clock {
0264     const char *name;
0265     const char *parent_name;
0266     const struct clk_ops *ops;
0267     struct clk_hw hw;
0268     struct __prci_wrpll_data *pwd;
0269     struct __prci_data *pd;
0270 };
0271 
0272 #define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
0273 
0274 /*
0275  * struct prci_clk_desc - describes the information of clocks of each SoCs
0276  * @clks: point to a array of __prci_clock
0277  * @num_clks: the number of element of clks
0278  */
0279 struct prci_clk_desc {
0280     struct __prci_clock *clks;
0281     size_t num_clks;
0282 };
0283 
0284 /* Core clock mux control */
0285 void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
0286 void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
0287 void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd);
0288 void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd);
0289 void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd);
0290 void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
0291 void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
0292 
0293 /* Linux clock framework integration */
0294 long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
0295                   unsigned long *parent_rate);
0296 int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
0297                    unsigned long parent_rate);
0298 int sifive_clk_is_enabled(struct clk_hw *hw);
0299 int sifive_prci_clock_enable(struct clk_hw *hw);
0300 void sifive_prci_clock_disable(struct clk_hw *hw);
0301 unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
0302                         unsigned long parent_rate);
0303 unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
0304                            unsigned long parent_rate);
0305 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
0306                            unsigned long parent_rate);
0307 
0308 int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
0309 int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
0310 void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
0311 
0312 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */