xref: /openbmc/linux/drivers/clk/bcm/clk-iproc.h (revision becf1237)
15fe225c1SRay Jui /*
25fe225c1SRay Jui  * Copyright (C) 2014 Broadcom Corporation
35fe225c1SRay Jui  *
45fe225c1SRay Jui  * This program is free software; you can redistribute it and/or
55fe225c1SRay Jui  * modify it under the terms of the GNU General Public License as
65fe225c1SRay Jui  * published by the Free Software Foundation version 2.
75fe225c1SRay Jui  *
85fe225c1SRay Jui  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
95fe225c1SRay Jui  * kind, whether express or implied; without even the implied warranty
105fe225c1SRay Jui  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
115fe225c1SRay Jui  * GNU General Public License for more details.
125fe225c1SRay Jui  */
135fe225c1SRay Jui 
145fe225c1SRay Jui #ifndef _CLK_IPROC_H
155fe225c1SRay Jui #define _CLK_IPROC_H
165fe225c1SRay Jui 
175fe225c1SRay Jui #include <linux/kernel.h>
185fe225c1SRay Jui #include <linux/list.h>
195fe225c1SRay Jui #include <linux/spinlock.h>
205fe225c1SRay Jui #include <linux/slab.h>
215fe225c1SRay Jui #include <linux/device.h>
225fe225c1SRay Jui #include <linux/of.h>
235fe225c1SRay Jui #include <linux/clk-provider.h>
245fe225c1SRay Jui 
255fe225c1SRay Jui #define IPROC_CLK_NAME_LEN 25
265fe225c1SRay Jui #define IPROC_CLK_INVALID_OFFSET 0xffffffff
275fe225c1SRay Jui #define bit_mask(width) ((1 << (width)) - 1)
285fe225c1SRay Jui 
295fe225c1SRay Jui /* clocks that should not be disabled at runtime */
305fe225c1SRay Jui #define IPROC_CLK_AON BIT(0)
315fe225c1SRay Jui 
325fe225c1SRay Jui /* PLL that requires gating through ASIU */
335fe225c1SRay Jui #define IPROC_CLK_PLL_ASIU BIT(1)
345fe225c1SRay Jui 
355fe225c1SRay Jui /* PLL that has fractional part of the NDIV */
365fe225c1SRay Jui #define IPROC_CLK_PLL_HAS_NDIV_FRAC BIT(2)
375fe225c1SRay Jui 
385fe225c1SRay Jui /*
395fe225c1SRay Jui  * Some of the iProc PLL/clocks may have an ASIC bug that requires read back
405fe225c1SRay Jui  * of the same register following the write to flush the write transaction into
415fe225c1SRay Jui  * the intended register
425fe225c1SRay Jui  */
435fe225c1SRay Jui #define IPROC_CLK_NEEDS_READ_BACK BIT(3)
445fe225c1SRay Jui 
455fe225c1SRay Jui /*
465fe225c1SRay Jui  * Some PLLs require the PLL SW override bit to be set before changes can be
475fe225c1SRay Jui  * applied to the PLL
485fe225c1SRay Jui  */
495fe225c1SRay Jui #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
505fe225c1SRay Jui 
515fe225c1SRay Jui /*
5201b6722fSJon Mason  * Some PLLs use a different way to control clock power, via the PWRDWN bit in
5301b6722fSJon Mason  * the PLL control register
5401b6722fSJon Mason  */
5501b6722fSJon Mason #define IPROC_CLK_EMBED_PWRCTRL BIT(5)
5601b6722fSJon Mason 
5701b6722fSJon Mason /*
5840c8bec3SJon Mason  * Some PLLs have separate registers for Status and Control.  Identify this to
5940c8bec3SJon Mason  * let the driver know if additional registers need to be used
6040c8bec3SJon Mason  */
6140c8bec3SJon Mason #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
6240c8bec3SJon Mason 
6340c8bec3SJon Mason /*
64bcd8be13SSimran Rai  * Some PLLs have an additional divide by 2 in master clock calculation;
65bcd8be13SSimran Rai  * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know
66bcd8be13SSimran Rai  * of modified calculations
67bcd8be13SSimran Rai  */
68bcd8be13SSimran Rai #define IPROC_CLK_MCLK_DIV_BY_2 BIT(7)
69bcd8be13SSimran Rai 
70bcd8be13SSimran Rai /*
71bcd8be13SSimran Rai  * Some PLLs provide a look up table for the leaf clock frequencies and
72bcd8be13SSimran Rai  * auto calculates VCO frequency parameters based on the provided leaf
73bcd8be13SSimran Rai  * clock frequencies. They have a user mode that allows the divider
74bcd8be13SSimran Rai  * controls to be determined by the user
75bcd8be13SSimran Rai  */
76bcd8be13SSimran Rai #define IPROC_CLK_PLL_USER_MODE_ON BIT(8)
77bcd8be13SSimran Rai 
78bcd8be13SSimran Rai /*
79bcd8be13SSimran Rai  * Some PLLs have an active low reset
80bcd8be13SSimran Rai  */
81bcd8be13SSimran Rai #define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9)
82bcd8be13SSimran Rai 
83bcd8be13SSimran Rai /*
84becf1237SLori Hikichi  * Calculate the PLL parameters are runtime, instead of using table
85becf1237SLori Hikichi  */
86becf1237SLori Hikichi #define IPROC_CLK_PLL_CALC_PARAM BIT(10)
87becf1237SLori Hikichi 
88becf1237SLori Hikichi /*
895fe225c1SRay Jui  * Parameters for VCO frequency configuration
905fe225c1SRay Jui  *
915fe225c1SRay Jui  * VCO frequency =
925fe225c1SRay Jui  * ((ndiv_int + ndiv_frac / 2^20) * (ref freqeuncy  / pdiv)
935fe225c1SRay Jui  */
945fe225c1SRay Jui struct iproc_pll_vco_param {
955fe225c1SRay Jui 	unsigned long rate;
965fe225c1SRay Jui 	unsigned int ndiv_int;
975fe225c1SRay Jui 	unsigned int ndiv_frac;
985fe225c1SRay Jui 	unsigned int pdiv;
995fe225c1SRay Jui };
1005fe225c1SRay Jui 
1015fe225c1SRay Jui struct iproc_clk_reg_op {
1025fe225c1SRay Jui 	unsigned int offset;
1035fe225c1SRay Jui 	unsigned int shift;
1045fe225c1SRay Jui 	unsigned int width;
1055fe225c1SRay Jui };
1065fe225c1SRay Jui 
1075fe225c1SRay Jui /*
1085fe225c1SRay Jui  * Clock gating control at the top ASIU level
1095fe225c1SRay Jui  */
1105fe225c1SRay Jui struct iproc_asiu_gate {
1115fe225c1SRay Jui 	unsigned int offset;
1125fe225c1SRay Jui 	unsigned int en_shift;
1135fe225c1SRay Jui };
1145fe225c1SRay Jui 
1155fe225c1SRay Jui /*
1165fe225c1SRay Jui  * Control of powering on/off of a PLL
1175fe225c1SRay Jui  *
1185fe225c1SRay Jui  * Before powering off a PLL, input isolation (ISO) needs to be enabled
1195fe225c1SRay Jui  */
1205fe225c1SRay Jui struct iproc_pll_aon_pwr_ctrl {
1215fe225c1SRay Jui 	unsigned int offset;
1225fe225c1SRay Jui 	unsigned int pwr_width;
1235fe225c1SRay Jui 	unsigned int pwr_shift;
1245fe225c1SRay Jui 	unsigned int iso_shift;
1255fe225c1SRay Jui };
1265fe225c1SRay Jui 
1275fe225c1SRay Jui /*
128f713c6bfSJon Mason  * Control of the PLL reset
1295fe225c1SRay Jui  */
1305fe225c1SRay Jui struct iproc_pll_reset_ctrl {
1315fe225c1SRay Jui 	unsigned int offset;
1325fe225c1SRay Jui 	unsigned int reset_shift;
1335fe225c1SRay Jui 	unsigned int p_reset_shift;
134f713c6bfSJon Mason };
135f713c6bfSJon Mason 
136f713c6bfSJon Mason /*
137f713c6bfSJon Mason  * Control of the Ki, Kp, and Ka parameters
138f713c6bfSJon Mason  */
139f713c6bfSJon Mason struct iproc_pll_dig_filter_ctrl {
140f713c6bfSJon Mason 	unsigned int offset;
1415fe225c1SRay Jui 	unsigned int ki_shift;
1425fe225c1SRay Jui 	unsigned int ki_width;
1435fe225c1SRay Jui 	unsigned int kp_shift;
1445fe225c1SRay Jui 	unsigned int kp_width;
1455fe225c1SRay Jui 	unsigned int ka_shift;
1465fe225c1SRay Jui 	unsigned int ka_width;
1475fe225c1SRay Jui };
1485fe225c1SRay Jui 
1495fe225c1SRay Jui /*
1505fe225c1SRay Jui  * To enable SW control of the PLL
1515fe225c1SRay Jui  */
1525fe225c1SRay Jui struct iproc_pll_sw_ctrl {
1535fe225c1SRay Jui 	unsigned int offset;
1545fe225c1SRay Jui 	unsigned int shift;
1555fe225c1SRay Jui };
1565fe225c1SRay Jui 
1575fe225c1SRay Jui struct iproc_pll_vco_ctrl {
1585fe225c1SRay Jui 	unsigned int u_offset;
1595fe225c1SRay Jui 	unsigned int l_offset;
1605fe225c1SRay Jui };
1615fe225c1SRay Jui 
1625fe225c1SRay Jui /*
1635fe225c1SRay Jui  * Main PLL control parameters
1645fe225c1SRay Jui  */
1655fe225c1SRay Jui struct iproc_pll_ctrl {
1665fe225c1SRay Jui 	unsigned long flags;
1675fe225c1SRay Jui 	struct iproc_pll_aon_pwr_ctrl aon;
1685fe225c1SRay Jui 	struct iproc_asiu_gate asiu;
1695fe225c1SRay Jui 	struct iproc_pll_reset_ctrl reset;
170f713c6bfSJon Mason 	struct iproc_pll_dig_filter_ctrl dig_filter;
1715fe225c1SRay Jui 	struct iproc_pll_sw_ctrl sw_ctrl;
1725fe225c1SRay Jui 	struct iproc_clk_reg_op ndiv_int;
1735fe225c1SRay Jui 	struct iproc_clk_reg_op ndiv_frac;
1745fe225c1SRay Jui 	struct iproc_clk_reg_op pdiv;
1755fe225c1SRay Jui 	struct iproc_pll_vco_ctrl vco_ctrl;
1765fe225c1SRay Jui 	struct iproc_clk_reg_op status;
177bcd8be13SSimran Rai 	struct iproc_clk_reg_op macro_mode;
1785fe225c1SRay Jui };
1795fe225c1SRay Jui 
1805fe225c1SRay Jui /*
1815fe225c1SRay Jui  * Controls enabling/disabling a PLL derived clock
1825fe225c1SRay Jui  */
1835fe225c1SRay Jui struct iproc_clk_enable_ctrl {
1845fe225c1SRay Jui 	unsigned int offset;
1855fe225c1SRay Jui 	unsigned int enable_shift;
1865fe225c1SRay Jui 	unsigned int hold_shift;
1875fe225c1SRay Jui 	unsigned int bypass_shift;
1885fe225c1SRay Jui };
1895fe225c1SRay Jui 
1905fe225c1SRay Jui /*
1915fe225c1SRay Jui  * Main clock control parameters for clocks derived from the PLLs
1925fe225c1SRay Jui  */
1935fe225c1SRay Jui struct iproc_clk_ctrl {
1945fe225c1SRay Jui 	unsigned int channel;
1955fe225c1SRay Jui 	unsigned long flags;
1965fe225c1SRay Jui 	struct iproc_clk_enable_ctrl enable;
1975fe225c1SRay Jui 	struct iproc_clk_reg_op mdiv;
1985fe225c1SRay Jui };
1995fe225c1SRay Jui 
2005fe225c1SRay Jui /*
2015fe225c1SRay Jui  * Divisor of the ASIU clocks
2025fe225c1SRay Jui  */
2035fe225c1SRay Jui struct iproc_asiu_div {
2045fe225c1SRay Jui 	unsigned int offset;
2055fe225c1SRay Jui 	unsigned int en_shift;
2065fe225c1SRay Jui 	unsigned int high_shift;
2075fe225c1SRay Jui 	unsigned int high_width;
2085fe225c1SRay Jui 	unsigned int low_shift;
2095fe225c1SRay Jui 	unsigned int low_width;
2105fe225c1SRay Jui };
2115fe225c1SRay Jui 
212df416e56SRay Jui void iproc_armpll_setup(struct device_node *node);
213df416e56SRay Jui void iproc_pll_clk_setup(struct device_node *node,
2145fe225c1SRay Jui 			 const struct iproc_pll_ctrl *pll_ctrl,
2155fe225c1SRay Jui 			 const struct iproc_pll_vco_param *vco,
2165fe225c1SRay Jui 			 unsigned int num_vco_entries,
2175fe225c1SRay Jui 			 const struct iproc_clk_ctrl *clk_ctrl,
2185fe225c1SRay Jui 			 unsigned int num_clks);
219df416e56SRay Jui void iproc_asiu_setup(struct device_node *node,
2205fe225c1SRay Jui 		      const struct iproc_asiu_div *div,
2215fe225c1SRay Jui 		      const struct iproc_asiu_gate *gate,
2225fe225c1SRay Jui 		      unsigned int num_clks);
2235fe225c1SRay Jui 
2245fe225c1SRay Jui #endif /* _CLK_IPROC_H */
225