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