xref: /openbmc/linux/drivers/media/i2c/ccs-pll.h (revision 8a75e8dc)
19e05bbacSSakari Ailus /* SPDX-License-Identifier: GPL-2.0-only */
29e05bbacSSakari Ailus /*
39e05bbacSSakari Ailus  * drivers/media/i2c/ccs-pll.h
49e05bbacSSakari Ailus  *
59e05bbacSSakari Ailus  * Generic MIPI CCS/SMIA/SMIA++ PLL calculator
69e05bbacSSakari Ailus  *
79e05bbacSSakari Ailus  * Copyright (C) 2020 Intel Corporation
89e05bbacSSakari Ailus  * Copyright (C) 2012 Nokia Corporation
97389d01cSSakari Ailus  * Contact: Sakari Ailus <sakari.ailus@linux.intel.com>
109e05bbacSSakari Ailus  */
119e05bbacSSakari Ailus 
129e05bbacSSakari Ailus #ifndef CCS_PLL_H
139e05bbacSSakari Ailus #define CCS_PLL_H
149e05bbacSSakari Ailus 
154f3d9e6eSSakari Ailus #include <linux/bits.h>
164f3d9e6eSSakari Ailus 
179e05bbacSSakari Ailus /* CSI-2 or CCP-2 */
1847b6eaf3SSakari Ailus #define CCS_PLL_BUS_TYPE_CSI2_DPHY				0x00
1947b6eaf3SSakari Ailus #define CCS_PLL_BUS_TYPE_CSI2_CPHY				0x01
209e05bbacSSakari Ailus 
214f3d9e6eSSakari Ailus /* Old SMIA and implementation specific flags */
229e05bbacSSakari Ailus /* op pix clock is for all lanes in total normally */
234f3d9e6eSSakari Ailus #define CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE			BIT(0)
244f3d9e6eSSakari Ailus #define CCS_PLL_FLAG_NO_OP_CLOCKS				BIT(1)
25cac8f5d2SSakari Ailus /* CCS PLL flags */
26cac8f5d2SSakari Ailus #define CCS_PLL_FLAG_LANE_SPEED_MODEL				BIT(2)
27ae502e08SSakari Ailus #define CCS_PLL_FLAG_LINK_DECOUPLED				BIT(3)
284e1e8d24SSakari Ailus #define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER				BIT(4)
299490a227SSakari Ailus #define CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV			BIT(5)
3038c94eb8SSakari Ailus #define CCS_PLL_FLAG_FIFO_DERATING				BIT(6)
3138c94eb8SSakari Ailus #define CCS_PLL_FLAG_FIFO_OVERRATING				BIT(7)
326c7469e4SSakari Ailus #define CCS_PLL_FLAG_DUAL_PLL					BIT(8)
33900c33e8SSakari Ailus #define CCS_PLL_FLAG_OP_SYS_DDR					BIT(9)
34900c33e8SSakari Ailus #define CCS_PLL_FLAG_OP_PIX_DDR					BIT(10)
359e05bbacSSakari Ailus 
36925e3e49SSakari Ailus /**
37925e3e49SSakari Ailus  * struct ccs_pll_branch_fr - CCS PLL configuration (front)
38925e3e49SSakari Ailus  *
39925e3e49SSakari Ailus  * A single branch front-end of the CCS PLL tree.
40925e3e49SSakari Ailus  *
41925e3e49SSakari Ailus  * @pre_pll_clk_div: Pre-PLL clock divisor
42925e3e49SSakari Ailus  * @pll_multiplier: PLL multiplier
43925e3e49SSakari Ailus  * @pll_ip_clk_freq_hz: PLL input clock frequency
44925e3e49SSakari Ailus  * @pll_op_clk_freq_hz: PLL output clock frequency
45925e3e49SSakari Ailus  */
46415ddd99SSakari Ailus struct ccs_pll_branch_fr {
47*8a75e8dcSSakari Ailus 	u16 pre_pll_clk_div;
48*8a75e8dcSSakari Ailus 	u16 pll_multiplier;
49*8a75e8dcSSakari Ailus 	u32 pll_ip_clk_freq_hz;
50*8a75e8dcSSakari Ailus 	u32 pll_op_clk_freq_hz;
51415ddd99SSakari Ailus };
52415ddd99SSakari Ailus 
53925e3e49SSakari Ailus /**
54925e3e49SSakari Ailus  * struct ccs_pll_branch_bk - CCS PLL configuration (back)
55925e3e49SSakari Ailus  *
56925e3e49SSakari Ailus  * A single branch back-end of the CCS PLL tree.
57925e3e49SSakari Ailus  *
58925e3e49SSakari Ailus  * @sys_clk_div: System clock divider
59925e3e49SSakari Ailus  * @pix_clk_div: Pixel clock divider
60925e3e49SSakari Ailus  * @sys_clk_freq_hz: System clock frequency
61925e3e49SSakari Ailus  * @pix_clk_freq_hz: Pixel clock frequency
62925e3e49SSakari Ailus  */
63415ddd99SSakari Ailus struct ccs_pll_branch_bk {
64*8a75e8dcSSakari Ailus 	u16 sys_clk_div;
65*8a75e8dcSSakari Ailus 	u16 pix_clk_div;
66*8a75e8dcSSakari Ailus 	u32 sys_clk_freq_hz;
67*8a75e8dcSSakari Ailus 	u32 pix_clk_freq_hz;
689e05bbacSSakari Ailus };
699e05bbacSSakari Ailus 
70925e3e49SSakari Ailus /**
71925e3e49SSakari Ailus  * struct ccs_pll - Full CCS PLL configuration
72925e3e49SSakari Ailus  *
73925e3e49SSakari Ailus  * All information required to calculate CCS PLL configuration.
74925e3e49SSakari Ailus  *
75925e3e49SSakari Ailus  * @bus_type: Type of the data bus, CCS_PLL_BUS_TYPE_* (input)
76cac8f5d2SSakari Ailus  * @op_lanes: Number of operational lanes (input)
77cac8f5d2SSakari Ailus  * @vt_lanes: Number of video timing lanes (input)
78925e3e49SSakari Ailus  * @csi2: CSI-2 related parameters
79925e3e49SSakari Ailus  * @csi2.lanes: The number of the CSI-2 data lanes (input)
80925e3e49SSakari Ailus  * @binning_vertical: Vertical binning factor (input)
81925e3e49SSakari Ailus  * @binning_horizontal: Horizontal binning factor (input)
82925e3e49SSakari Ailus  * @scale_m: Downscaling factor, M component, [16, max] (input)
83925e3e49SSakari Ailus  * @scale_n: Downscaling factor, N component, typically 16 (input)
84925e3e49SSakari Ailus  * @bits_per_pixel: Bits per pixel on the output data bus (input)
85c4c0b222SSakari Ailus  * @op_bits_per_lane: Number of bits per OP lane (input)
86925e3e49SSakari Ailus  * @flags: CCS_PLL_FLAG_* (input)
87925e3e49SSakari Ailus  * @link_freq: Chosen link frequency (input)
88925e3e49SSakari Ailus  * @ext_clk_freq_hz: External clock frequency, i.e. the sensor's input clock
89925e3e49SSakari Ailus  *		     (input)
90925e3e49SSakari Ailus  * @vt_fr: Video timing front-end configuration (output)
91925e3e49SSakari Ailus  * @vt_bk: Video timing back-end configuration (output)
92f25d3962SSakari Ailus  * @op_fr: Operational timing front-end configuration (output)
93925e3e49SSakari Ailus  * @op_bk: Operational timing back-end configuration (output)
94925e3e49SSakari Ailus  * @pixel_rate_csi: Pixel rate on the output data bus (output)
95925e3e49SSakari Ailus  * @pixel_rate_pixel_array: Nominal pixel rate in the sensor's pixel array
96925e3e49SSakari Ailus  *			    (output)
97925e3e49SSakari Ailus  */
989e05bbacSSakari Ailus struct ccs_pll {
999e05bbacSSakari Ailus 	/* input values */
100*8a75e8dcSSakari Ailus 	u8 bus_type;
101*8a75e8dcSSakari Ailus 	u8 op_lanes;
102*8a75e8dcSSakari Ailus 	u8 vt_lanes;
1039e05bbacSSakari Ailus 	struct {
104*8a75e8dcSSakari Ailus 		u8 lanes;
1059e05bbacSSakari Ailus 	} csi2;
106*8a75e8dcSSakari Ailus 	u8 binning_horizontal;
107*8a75e8dcSSakari Ailus 	u8 binning_vertical;
108*8a75e8dcSSakari Ailus 	u8 scale_m;
109*8a75e8dcSSakari Ailus 	u8 scale_n;
110*8a75e8dcSSakari Ailus 	u8 bits_per_pixel;
111*8a75e8dcSSakari Ailus 	u8 op_bits_per_lane;
112*8a75e8dcSSakari Ailus 	u16 flags;
113*8a75e8dcSSakari Ailus 	u32 link_freq;
114*8a75e8dcSSakari Ailus 	u32 ext_clk_freq_hz;
1159e05bbacSSakari Ailus 
1169e05bbacSSakari Ailus 	/* output values */
117415ddd99SSakari Ailus 	struct ccs_pll_branch_fr vt_fr;
118415ddd99SSakari Ailus 	struct ccs_pll_branch_bk vt_bk;
119f25d3962SSakari Ailus 	struct ccs_pll_branch_fr op_fr;
120415ddd99SSakari Ailus 	struct ccs_pll_branch_bk op_bk;
1219e05bbacSSakari Ailus 
122*8a75e8dcSSakari Ailus 	u32 pixel_rate_csi;
123*8a75e8dcSSakari Ailus 	u32 pixel_rate_pixel_array;
1249e05bbacSSakari Ailus };
1259e05bbacSSakari Ailus 
126925e3e49SSakari Ailus /**
127925e3e49SSakari Ailus  * struct ccs_pll_branch_limits_fr - CCS PLL front-end limits
128925e3e49SSakari Ailus  *
129925e3e49SSakari Ailus  * @min_pre_pll_clk_div: Minimum pre-PLL clock divider
130925e3e49SSakari Ailus  * @max_pre_pll_clk_div: Maximum pre-PLL clock divider
131925e3e49SSakari Ailus  * @min_pll_ip_clk_freq_hz: Minimum PLL input clock frequency
132925e3e49SSakari Ailus  * @max_pll_ip_clk_freq_hz: Maximum PLL input clock frequency
133925e3e49SSakari Ailus  * @min_pll_multiplier: Minimum PLL multiplier
134925e3e49SSakari Ailus  * @max_pll_multiplier: Maximum PLL multiplier
135925e3e49SSakari Ailus  * @min_pll_op_clk_freq_hz: Minimum PLL output clock frequency
136925e3e49SSakari Ailus  * @max_pll_op_clk_freq_hz: Maximum PLL output clock frequency
137925e3e49SSakari Ailus  */
138415ddd99SSakari Ailus struct ccs_pll_branch_limits_fr {
139*8a75e8dcSSakari Ailus 	u16 min_pre_pll_clk_div;
140*8a75e8dcSSakari Ailus 	u16 max_pre_pll_clk_div;
141*8a75e8dcSSakari Ailus 	u32 min_pll_ip_clk_freq_hz;
142*8a75e8dcSSakari Ailus 	u32 max_pll_ip_clk_freq_hz;
143*8a75e8dcSSakari Ailus 	u16 min_pll_multiplier;
144*8a75e8dcSSakari Ailus 	u16 max_pll_multiplier;
145*8a75e8dcSSakari Ailus 	u32 min_pll_op_clk_freq_hz;
146*8a75e8dcSSakari Ailus 	u32 max_pll_op_clk_freq_hz;
147415ddd99SSakari Ailus };
148415ddd99SSakari Ailus 
149925e3e49SSakari Ailus /**
150925e3e49SSakari Ailus  * struct ccs_pll_branch_limits_bk - CCS PLL back-end limits
151925e3e49SSakari Ailus  *
152925e3e49SSakari Ailus  * @min_sys_clk_div: Minimum system clock divider
153925e3e49SSakari Ailus  * @max_sys_clk_div: Maximum system clock divider
154925e3e49SSakari Ailus  * @min_sys_clk_freq_hz: Minimum system clock frequency
155925e3e49SSakari Ailus  * @max_sys_clk_freq_hz: Maximum system clock frequency
156925e3e49SSakari Ailus  * @min_pix_clk_div: Minimum pixel clock divider
157925e3e49SSakari Ailus  * @max_pix_clk_div: Maximum pixel clock divider
158925e3e49SSakari Ailus  * @min_pix_clk_freq_hz: Minimum pixel clock frequency
159925e3e49SSakari Ailus  * @max_pix_clk_freq_hz: Maximum pixel clock frequency
160925e3e49SSakari Ailus  */
161415ddd99SSakari Ailus struct ccs_pll_branch_limits_bk {
162*8a75e8dcSSakari Ailus 	u16 min_sys_clk_div;
163*8a75e8dcSSakari Ailus 	u16 max_sys_clk_div;
164*8a75e8dcSSakari Ailus 	u32 min_sys_clk_freq_hz;
165*8a75e8dcSSakari Ailus 	u32 max_sys_clk_freq_hz;
166*8a75e8dcSSakari Ailus 	u16 min_pix_clk_div;
167*8a75e8dcSSakari Ailus 	u16 max_pix_clk_div;
168*8a75e8dcSSakari Ailus 	u32 min_pix_clk_freq_hz;
169*8a75e8dcSSakari Ailus 	u32 max_pix_clk_freq_hz;
1709e05bbacSSakari Ailus };
1719e05bbacSSakari Ailus 
172925e3e49SSakari Ailus /**
173925e3e49SSakari Ailus  * struct ccs_pll_limits - CCS PLL limits
174925e3e49SSakari Ailus  *
175925e3e49SSakari Ailus  * @min_ext_clk_freq_hz: Minimum external clock frequency
176925e3e49SSakari Ailus  * @max_ext_clk_freq_hz: Maximum external clock frequency
177925e3e49SSakari Ailus  * @vt_fr: Video timing front-end limits
178925e3e49SSakari Ailus  * @vt_bk: Video timing back-end limits
179f25d3962SSakari Ailus  * @op_fr: Operational timing front-end limits
180925e3e49SSakari Ailus  * @op_bk: Operational timing back-end limits
181925e3e49SSakari Ailus  * @min_line_length_pck_bin: Minimum line length in pixels, with binning
182925e3e49SSakari Ailus  * @min_line_length_pck: Minimum line length in pixels without binning
183925e3e49SSakari Ailus  */
1849e05bbacSSakari Ailus struct ccs_pll_limits {
1859e05bbacSSakari Ailus 	/* Strict PLL limits */
186*8a75e8dcSSakari Ailus 	u32 min_ext_clk_freq_hz;
187*8a75e8dcSSakari Ailus 	u32 max_ext_clk_freq_hz;
1889e05bbacSSakari Ailus 
189415ddd99SSakari Ailus 	struct ccs_pll_branch_limits_fr vt_fr;
190415ddd99SSakari Ailus 	struct ccs_pll_branch_limits_bk vt_bk;
191f25d3962SSakari Ailus 	struct ccs_pll_branch_limits_fr op_fr;
192415ddd99SSakari Ailus 	struct ccs_pll_branch_limits_bk op_bk;
1939e05bbacSSakari Ailus 
1949e05bbacSSakari Ailus 	/* Other relevant limits */
195*8a75e8dcSSakari Ailus 	u32 min_line_length_pck_bin;
196*8a75e8dcSSakari Ailus 	u32 min_line_length_pck;
1979e05bbacSSakari Ailus };
1989e05bbacSSakari Ailus 
1999e05bbacSSakari Ailus struct device;
2009e05bbacSSakari Ailus 
201925e3e49SSakari Ailus /**
202925e3e49SSakari Ailus  * ccs_pll_calculate - Calculate CCS PLL configuration based on input parameters
203925e3e49SSakari Ailus  *
204925e3e49SSakari Ailus  * @dev: Device pointer, used for printing messages
205925e3e49SSakari Ailus  * @limits: Limits specific to the sensor
206925e3e49SSakari Ailus  * @pll: Given PLL configuration
207925e3e49SSakari Ailus  *
208925e3e49SSakari Ailus  * Calculate the CCS PLL configuration based on the limits as well as given
209925e3e49SSakari Ailus  * device specific, system specific or user configured input data.
210925e3e49SSakari Ailus  */
2119e05bbacSSakari Ailus int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits,
2129e05bbacSSakari Ailus 		      struct ccs_pll *pll);
2139e05bbacSSakari Ailus 
2149e05bbacSSakari Ailus #endif /* CCS_PLL_H */
215