xref: /openbmc/linux/drivers/clk/bcm/clk-iproc.h (revision 52e6676e)
1*52e6676eSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2*52e6676eSThomas Gleixner /* Copyright (C) 2014 Broadcom Corporation */
35fe225c1SRay Jui 
45fe225c1SRay Jui #ifndef _CLK_IPROC_H
55fe225c1SRay Jui #define _CLK_IPROC_H
65fe225c1SRay Jui 
75fe225c1SRay Jui #include <linux/kernel.h>
85fe225c1SRay Jui #include <linux/list.h>
95fe225c1SRay Jui #include <linux/spinlock.h>
105fe225c1SRay Jui #include <linux/slab.h>
115fe225c1SRay Jui #include <linux/device.h>
125fe225c1SRay Jui #include <linux/of.h>
135fe225c1SRay Jui #include <linux/clk-provider.h>
145fe225c1SRay Jui 
155fe225c1SRay Jui #define IPROC_CLK_NAME_LEN 25
165fe225c1SRay Jui #define IPROC_CLK_INVALID_OFFSET 0xffffffff
175fe225c1SRay Jui #define bit_mask(width) ((1 << (width)) - 1)
185fe225c1SRay Jui 
195fe225c1SRay Jui /* clocks that should not be disabled at runtime */
205fe225c1SRay Jui #define IPROC_CLK_AON BIT(0)
215fe225c1SRay Jui 
225fe225c1SRay Jui /* PLL that requires gating through ASIU */
235fe225c1SRay Jui #define IPROC_CLK_PLL_ASIU BIT(1)
245fe225c1SRay Jui 
255fe225c1SRay Jui /* PLL that has fractional part of the NDIV */
265fe225c1SRay Jui #define IPROC_CLK_PLL_HAS_NDIV_FRAC BIT(2)
275fe225c1SRay Jui 
285fe225c1SRay Jui /*
295fe225c1SRay Jui  * Some of the iProc PLL/clocks may have an ASIC bug that requires read back
305fe225c1SRay Jui  * of the same register following the write to flush the write transaction into
315fe225c1SRay Jui  * the intended register
325fe225c1SRay Jui  */
335fe225c1SRay Jui #define IPROC_CLK_NEEDS_READ_BACK BIT(3)
345fe225c1SRay Jui 
355fe225c1SRay Jui /*
365fe225c1SRay Jui  * Some PLLs require the PLL SW override bit to be set before changes can be
375fe225c1SRay Jui  * applied to the PLL
385fe225c1SRay Jui  */
395fe225c1SRay Jui #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
405fe225c1SRay Jui 
415fe225c1SRay Jui /*
4201b6722fSJon Mason  * Some PLLs use a different way to control clock power, via the PWRDWN bit in
4301b6722fSJon Mason  * the PLL control register
4401b6722fSJon Mason  */
4501b6722fSJon Mason #define IPROC_CLK_EMBED_PWRCTRL BIT(5)
4601b6722fSJon Mason 
4701b6722fSJon Mason /*
4840c8bec3SJon Mason  * Some PLLs have separate registers for Status and Control.  Identify this to
4940c8bec3SJon Mason  * let the driver know if additional registers need to be used
5040c8bec3SJon Mason  */
5140c8bec3SJon Mason #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
5240c8bec3SJon Mason 
5340c8bec3SJon Mason /*
54bcd8be13SSimran Rai  * Some PLLs have an additional divide by 2 in master clock calculation;
55bcd8be13SSimran Rai  * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know
56bcd8be13SSimran Rai  * of modified calculations
57bcd8be13SSimran Rai  */
58bcd8be13SSimran Rai #define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)
59bcd8be13SSimran Rai 
60bcd8be13SSimran Rai /*
61bcd8be13SSimran Rai  * Some PLLs provide a look up table for the leaf clock frequencies and
62bcd8be13SSimran Rai  * auto calculates VCO frequency parameters based on the provided leaf
63bcd8be13SSimran Rai  * clock frequencies. They have a user mode that allows the divider
64bcd8be13SSimran Rai  * controls to be determined by the user
65bcd8be13SSimran Rai  */
66bcd8be13SSimran Rai #define IPROC_CLK_PLL_USER_MODE_ON BIT(8)
67bcd8be13SSimran Rai 
68bcd8be13SSimran Rai /*
69bcd8be13SSimran Rai  * Some PLLs have an active low reset
70bcd8be13SSimran Rai  */
71bcd8be13SSimran Rai #define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)
72bcd8be13SSimran Rai 
73bcd8be13SSimran Rai /*
74becf1237SLori Hikichi  * Calculate the PLL parameters are runtime, instead of using table
75becf1237SLori Hikichi  */
76becf1237SLori Hikichi #define IPROC_CLK_PLL_CALC_PARAM BIT(10)
77becf1237SLori Hikichi 
78becf1237SLori Hikichi /*
795fe225c1SRay Jui  * Parameters for VCO frequency configuration
805fe225c1SRay Jui  *
815fe225c1SRay Jui  * VCO frequency =
827c55e8efSTom Rix  * ((ndiv_int + ndiv_frac / 2^20) * (ref frequency  / pdiv)
835fe225c1SRay Jui  */
845fe225c1SRay Jui struct iproc_pll_vco_param {
855fe225c1SRay Jui 	unsigned long rate;
865fe225c1SRay Jui 	unsigned int ndiv_int;
875fe225c1SRay Jui 	unsigned int ndiv_frac;
885fe225c1SRay Jui 	unsigned int pdiv;
895fe225c1SRay Jui };
905fe225c1SRay Jui 
915fe225c1SRay Jui struct iproc_clk_reg_op {
925fe225c1SRay Jui 	unsigned int offset;
935fe225c1SRay Jui 	unsigned int shift;
945fe225c1SRay Jui 	unsigned int width;
955fe225c1SRay Jui };
965fe225c1SRay Jui 
975fe225c1SRay Jui /*
985fe225c1SRay Jui  * Clock gating control at the top ASIU level
995fe225c1SRay Jui  */
1005fe225c1SRay Jui struct iproc_asiu_gate {
1015fe225c1SRay Jui 	unsigned int offset;
1025fe225c1SRay Jui 	unsigned int en_shift;
1035fe225c1SRay Jui };
1045fe225c1SRay Jui 
1055fe225c1SRay Jui /*
1065fe225c1SRay Jui  * Control of powering on/off of a PLL
1075fe225c1SRay Jui  *
1085fe225c1SRay Jui  * Before powering off a PLL, input isolation (ISO) needs to be enabled
1095fe225c1SRay Jui  */
1105fe225c1SRay Jui struct iproc_pll_aon_pwr_ctrl {
1115fe225c1SRay Jui 	unsigned int offset;
1125fe225c1SRay Jui 	unsigned int pwr_width;
1135fe225c1SRay Jui 	unsigned int pwr_shift;
1145fe225c1SRay Jui 	unsigned int iso_shift;
1155fe225c1SRay Jui };
1165fe225c1SRay Jui 
1175fe225c1SRay Jui /*
118f713c6bfSJon Mason  * Control of the PLL reset
1195fe225c1SRay Jui  */
1205fe225c1SRay Jui struct iproc_pll_reset_ctrl {
1215fe225c1SRay Jui 	unsigned int offset;
1225fe225c1SRay Jui 	unsigned int reset_shift;
1235fe225c1SRay Jui 	unsigned int p_reset_shift;
124f713c6bfSJon Mason };
125f713c6bfSJon Mason 
126f713c6bfSJon Mason /*
127f713c6bfSJon Mason  * Control of the Ki, Kp, and Ka parameters
128f713c6bfSJon Mason  */
129f713c6bfSJon Mason struct iproc_pll_dig_filter_ctrl {
130f713c6bfSJon Mason 	unsigned int offset;
1315fe225c1SRay Jui 	unsigned int ki_shift;
1325fe225c1SRay Jui 	unsigned int ki_width;
1335fe225c1SRay Jui 	unsigned int kp_shift;
1345fe225c1SRay Jui 	unsigned int kp_width;
1355fe225c1SRay Jui 	unsigned int ka_shift;
1365fe225c1SRay Jui 	unsigned int ka_width;
1375fe225c1SRay Jui };
1385fe225c1SRay Jui 
1395fe225c1SRay Jui /*
1405fe225c1SRay Jui  * To enable SW control of the PLL
1415fe225c1SRay Jui  */
1425fe225c1SRay Jui struct iproc_pll_sw_ctrl {
1435fe225c1SRay Jui 	unsigned int offset;
1445fe225c1SRay Jui 	unsigned int shift;
1455fe225c1SRay Jui };
1465fe225c1SRay Jui 
1475fe225c1SRay Jui struct iproc_pll_vco_ctrl {
1485fe225c1SRay Jui 	unsigned int u_offset;
1495fe225c1SRay Jui 	unsigned int l_offset;
1505fe225c1SRay Jui };
1515fe225c1SRay Jui 
1525fe225c1SRay Jui /*
1535fe225c1SRay Jui  * Main PLL control parameters
1545fe225c1SRay Jui  */
1555fe225c1SRay Jui struct iproc_pll_ctrl {
1565fe225c1SRay Jui 	unsigned long flags;
1575fe225c1SRay Jui 	struct iproc_pll_aon_pwr_ctrl aon;
1585fe225c1SRay Jui 	struct iproc_asiu_gate asiu;
1595fe225c1SRay Jui 	struct iproc_pll_reset_ctrl reset;
160f713c6bfSJon Mason 	struct iproc_pll_dig_filter_ctrl dig_filter;
1615fe225c1SRay Jui 	struct iproc_pll_sw_ctrl sw_ctrl;
1625fe225c1SRay Jui 	struct iproc_clk_reg_op ndiv_int;
1635fe225c1SRay Jui 	struct iproc_clk_reg_op ndiv_frac;
1645fe225c1SRay Jui 	struct iproc_clk_reg_op pdiv;
1655fe225c1SRay Jui 	struct iproc_pll_vco_ctrl vco_ctrl;
1665fe225c1SRay Jui 	struct iproc_clk_reg_op status;
167bcd8be13SSimran Rai 	struct iproc_clk_reg_op macro_mode;
1685fe225c1SRay Jui };
1695fe225c1SRay Jui 
1705fe225c1SRay Jui /*
1715fe225c1SRay Jui  * Controls enabling/disabling a PLL derived clock
1725fe225c1SRay Jui  */
1735fe225c1SRay Jui struct iproc_clk_enable_ctrl {
1745fe225c1SRay Jui 	unsigned int offset;
1755fe225c1SRay Jui 	unsigned int enable_shift;
1765fe225c1SRay Jui 	unsigned int hold_shift;
1775fe225c1SRay Jui 	unsigned int bypass_shift;
1785fe225c1SRay Jui };
1795fe225c1SRay Jui 
1805fe225c1SRay Jui /*
1815fe225c1SRay Jui  * Main clock control parameters for clocks derived from the PLLs
1825fe225c1SRay Jui  */
1835fe225c1SRay Jui struct iproc_clk_ctrl {
1845fe225c1SRay Jui 	unsigned int channel;
1855fe225c1SRay Jui 	unsigned long flags;
1865fe225c1SRay Jui 	struct iproc_clk_enable_ctrl enable;
1875fe225c1SRay Jui 	struct iproc_clk_reg_op mdiv;
1885fe225c1SRay Jui };
1895fe225c1SRay Jui 
1905fe225c1SRay Jui /*
1915fe225c1SRay Jui  * Divisor of the ASIU clocks
1925fe225c1SRay Jui  */
1935fe225c1SRay Jui struct iproc_asiu_div {
1945fe225c1SRay Jui 	unsigned int offset;
1955fe225c1SRay Jui 	unsigned int en_shift;
1965fe225c1SRay Jui 	unsigned int high_shift;
1975fe225c1SRay Jui 	unsigned int high_width;
1985fe225c1SRay Jui 	unsigned int low_shift;
1995fe225c1SRay Jui 	unsigned int low_width;
2005fe225c1SRay Jui };
2015fe225c1SRay Jui 
202df416e56SRay Jui void iproc_armpll_setup(struct device_node *node);
203df416e56SRay Jui void iproc_pll_clk_setup(struct device_node *node,
2045fe225c1SRay Jui 			 const struct iproc_pll_ctrl *pll_ctrl,
2055fe225c1SRay Jui 			 const struct iproc_pll_vco_param *vco,
2065fe225c1SRay Jui 			 unsigned int num_vco_entries,
2075fe225c1SRay Jui 			 const struct iproc_clk_ctrl *clk_ctrl,
2085fe225c1SRay Jui 			 unsigned int num_clks);
209df416e56SRay Jui void iproc_asiu_setup(struct device_node *node,
2105fe225c1SRay Jui 		      const struct iproc_asiu_div *div,
2115fe225c1SRay Jui 		      const struct iproc_asiu_gate *gate,
2125fe225c1SRay Jui 		      unsigned int num_clks);
2135fe225c1SRay Jui 
2145fe225c1SRay Jui #endif /* _CLK_IPROC_H */
215