xref: /openbmc/linux/drivers/clk/bcm/clk-iproc.h (revision f713c6bf)
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 /*
585fe225c1SRay Jui  * Parameters for VCO frequency configuration
595fe225c1SRay Jui  *
605fe225c1SRay Jui  * VCO frequency =
615fe225c1SRay Jui  * ((ndiv_int + ndiv_frac / 2^20) * (ref freqeuncy  / pdiv)
625fe225c1SRay Jui  */
635fe225c1SRay Jui struct iproc_pll_vco_param {
645fe225c1SRay Jui 	unsigned long rate;
655fe225c1SRay Jui 	unsigned int ndiv_int;
665fe225c1SRay Jui 	unsigned int ndiv_frac;
675fe225c1SRay Jui 	unsigned int pdiv;
685fe225c1SRay Jui };
695fe225c1SRay Jui 
705fe225c1SRay Jui struct iproc_clk_reg_op {
715fe225c1SRay Jui 	unsigned int offset;
725fe225c1SRay Jui 	unsigned int shift;
735fe225c1SRay Jui 	unsigned int width;
745fe225c1SRay Jui };
755fe225c1SRay Jui 
765fe225c1SRay Jui /*
775fe225c1SRay Jui  * Clock gating control at the top ASIU level
785fe225c1SRay Jui  */
795fe225c1SRay Jui struct iproc_asiu_gate {
805fe225c1SRay Jui 	unsigned int offset;
815fe225c1SRay Jui 	unsigned int en_shift;
825fe225c1SRay Jui };
835fe225c1SRay Jui 
845fe225c1SRay Jui /*
855fe225c1SRay Jui  * Control of powering on/off of a PLL
865fe225c1SRay Jui  *
875fe225c1SRay Jui  * Before powering off a PLL, input isolation (ISO) needs to be enabled
885fe225c1SRay Jui  */
895fe225c1SRay Jui struct iproc_pll_aon_pwr_ctrl {
905fe225c1SRay Jui 	unsigned int offset;
915fe225c1SRay Jui 	unsigned int pwr_width;
925fe225c1SRay Jui 	unsigned int pwr_shift;
935fe225c1SRay Jui 	unsigned int iso_shift;
945fe225c1SRay Jui };
955fe225c1SRay Jui 
965fe225c1SRay Jui /*
97f713c6bfSJon Mason  * Control of the PLL reset
985fe225c1SRay Jui  */
995fe225c1SRay Jui struct iproc_pll_reset_ctrl {
1005fe225c1SRay Jui 	unsigned int offset;
1015fe225c1SRay Jui 	unsigned int reset_shift;
1025fe225c1SRay Jui 	unsigned int p_reset_shift;
103f713c6bfSJon Mason };
104f713c6bfSJon Mason 
105f713c6bfSJon Mason /*
106f713c6bfSJon Mason  * Control of the Ki, Kp, and Ka parameters
107f713c6bfSJon Mason  */
108f713c6bfSJon Mason struct iproc_pll_dig_filter_ctrl {
109f713c6bfSJon Mason 	unsigned int offset;
1105fe225c1SRay Jui 	unsigned int ki_shift;
1115fe225c1SRay Jui 	unsigned int ki_width;
1125fe225c1SRay Jui 	unsigned int kp_shift;
1135fe225c1SRay Jui 	unsigned int kp_width;
1145fe225c1SRay Jui 	unsigned int ka_shift;
1155fe225c1SRay Jui 	unsigned int ka_width;
1165fe225c1SRay Jui };
1175fe225c1SRay Jui 
1185fe225c1SRay Jui /*
1195fe225c1SRay Jui  * To enable SW control of the PLL
1205fe225c1SRay Jui  */
1215fe225c1SRay Jui struct iproc_pll_sw_ctrl {
1225fe225c1SRay Jui 	unsigned int offset;
1235fe225c1SRay Jui 	unsigned int shift;
1245fe225c1SRay Jui };
1255fe225c1SRay Jui 
1265fe225c1SRay Jui struct iproc_pll_vco_ctrl {
1275fe225c1SRay Jui 	unsigned int u_offset;
1285fe225c1SRay Jui 	unsigned int l_offset;
1295fe225c1SRay Jui };
1305fe225c1SRay Jui 
1315fe225c1SRay Jui /*
1325fe225c1SRay Jui  * Main PLL control parameters
1335fe225c1SRay Jui  */
1345fe225c1SRay Jui struct iproc_pll_ctrl {
1355fe225c1SRay Jui 	unsigned long flags;
1365fe225c1SRay Jui 	struct iproc_pll_aon_pwr_ctrl aon;
1375fe225c1SRay Jui 	struct iproc_asiu_gate asiu;
1385fe225c1SRay Jui 	struct iproc_pll_reset_ctrl reset;
139f713c6bfSJon Mason 	struct iproc_pll_dig_filter_ctrl dig_filter;
1405fe225c1SRay Jui 	struct iproc_pll_sw_ctrl sw_ctrl;
1415fe225c1SRay Jui 	struct iproc_clk_reg_op ndiv_int;
1425fe225c1SRay Jui 	struct iproc_clk_reg_op ndiv_frac;
1435fe225c1SRay Jui 	struct iproc_clk_reg_op pdiv;
1445fe225c1SRay Jui 	struct iproc_pll_vco_ctrl vco_ctrl;
1455fe225c1SRay Jui 	struct iproc_clk_reg_op status;
1465fe225c1SRay Jui };
1475fe225c1SRay Jui 
1485fe225c1SRay Jui /*
1495fe225c1SRay Jui  * Controls enabling/disabling a PLL derived clock
1505fe225c1SRay Jui  */
1515fe225c1SRay Jui struct iproc_clk_enable_ctrl {
1525fe225c1SRay Jui 	unsigned int offset;
1535fe225c1SRay Jui 	unsigned int enable_shift;
1545fe225c1SRay Jui 	unsigned int hold_shift;
1555fe225c1SRay Jui 	unsigned int bypass_shift;
1565fe225c1SRay Jui };
1575fe225c1SRay Jui 
1585fe225c1SRay Jui /*
1595fe225c1SRay Jui  * Main clock control parameters for clocks derived from the PLLs
1605fe225c1SRay Jui  */
1615fe225c1SRay Jui struct iproc_clk_ctrl {
1625fe225c1SRay Jui 	unsigned int channel;
1635fe225c1SRay Jui 	unsigned long flags;
1645fe225c1SRay Jui 	struct iproc_clk_enable_ctrl enable;
1655fe225c1SRay Jui 	struct iproc_clk_reg_op mdiv;
1665fe225c1SRay Jui };
1675fe225c1SRay Jui 
1685fe225c1SRay Jui /*
1695fe225c1SRay Jui  * Divisor of the ASIU clocks
1705fe225c1SRay Jui  */
1715fe225c1SRay Jui struct iproc_asiu_div {
1725fe225c1SRay Jui 	unsigned int offset;
1735fe225c1SRay Jui 	unsigned int en_shift;
1745fe225c1SRay Jui 	unsigned int high_shift;
1755fe225c1SRay Jui 	unsigned int high_width;
1765fe225c1SRay Jui 	unsigned int low_shift;
1775fe225c1SRay Jui 	unsigned int low_width;
1785fe225c1SRay Jui };
1795fe225c1SRay Jui 
1805fe225c1SRay Jui void __init iproc_armpll_setup(struct device_node *node);
1815fe225c1SRay Jui void __init iproc_pll_clk_setup(struct device_node *node,
1825fe225c1SRay Jui 				const struct iproc_pll_ctrl *pll_ctrl,
1835fe225c1SRay Jui 				const struct iproc_pll_vco_param *vco,
1845fe225c1SRay Jui 				unsigned int num_vco_entries,
1855fe225c1SRay Jui 				const struct iproc_clk_ctrl *clk_ctrl,
1865fe225c1SRay Jui 				unsigned int num_clks);
1875fe225c1SRay Jui void __init iproc_asiu_setup(struct device_node *node,
1885fe225c1SRay Jui 			     const struct iproc_asiu_div *div,
1895fe225c1SRay Jui 			     const struct iproc_asiu_gate *gate,
1905fe225c1SRay Jui 			     unsigned int num_clks);
1915fe225c1SRay Jui 
1925fe225c1SRay Jui #endif /* _CLK_IPROC_H */
193