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