/* SPDX-License-Identifier: GPL-2.0-only */ /* * drivers/media/i2c/ccs-pll.h * * Generic MIPI CCS/SMIA/SMIA++ PLL calculator * * Copyright (C) 2020 Intel Corporation * Copyright (C) 2012 Nokia Corporation * Contact: Sakari Ailus */ #ifndef CCS_PLL_H #define CCS_PLL_H #include /* CSI-2 or CCP-2 */ #define CCS_PLL_BUS_TYPE_CSI2_DPHY 0x00 #define CCS_PLL_BUS_TYPE_CSI2_CPHY 0x01 /* Old SMIA and implementation specific flags */ /* op pix clock is for all lanes in total normally */ #define CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE BIT(0) #define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1) /* CCS PLL flags */ #define CCS_PLL_FLAG_LANE_SPEED_MODEL BIT(2) #define CCS_PLL_FLAG_LINK_DECOUPLED BIT(3) #define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER BIT(4) #define CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV BIT(5) #define CCS_PLL_FLAG_FIFO_DERATING BIT(6) #define CCS_PLL_FLAG_FIFO_OVERRATING BIT(7) #define CCS_PLL_FLAG_DUAL_PLL BIT(8) #define CCS_PLL_FLAG_OP_SYS_DDR BIT(9) #define CCS_PLL_FLAG_OP_PIX_DDR BIT(10) /** * struct ccs_pll_branch_fr - CCS PLL configuration (front) * * A single branch front-end of the CCS PLL tree. * * @pre_pll_clk_div: Pre-PLL clock divisor * @pll_multiplier: PLL multiplier * @pll_ip_clk_freq_hz: PLL input clock frequency * @pll_op_clk_freq_hz: PLL output clock frequency */ struct ccs_pll_branch_fr { uint16_t pre_pll_clk_div; uint16_t pll_multiplier; uint32_t pll_ip_clk_freq_hz; uint32_t pll_op_clk_freq_hz; }; /** * struct ccs_pll_branch_bk - CCS PLL configuration (back) * * A single branch back-end of the CCS PLL tree. * * @sys_clk_div: System clock divider * @pix_clk_div: Pixel clock divider * @sys_clk_freq_hz: System clock frequency * @pix_clk_freq_hz: Pixel clock frequency */ struct ccs_pll_branch_bk { uint16_t sys_clk_div; uint16_t pix_clk_div; uint32_t sys_clk_freq_hz; uint32_t pix_clk_freq_hz; }; /** * struct ccs_pll - Full CCS PLL configuration * * All information required to calculate CCS PLL configuration. * * @bus_type: Type of the data bus, CCS_PLL_BUS_TYPE_* (input) * @op_lanes: Number of operational lanes (input) * @vt_lanes: Number of video timing lanes (input) * @csi2: CSI-2 related parameters * @csi2.lanes: The number of the CSI-2 data lanes (input) * @binning_vertical: Vertical binning factor (input) * @binning_horizontal: Horizontal binning factor (input) * @scale_m: Downscaling factor, M component, [16, max] (input) * @scale_n: Downscaling factor, N component, typically 16 (input) * @bits_per_pixel: Bits per pixel on the output data bus (input) * @op_bits_per_lane: Number of bits per OP lane (input) * @flags: CCS_PLL_FLAG_* (input) * @link_freq: Chosen link frequency (input) * @ext_clk_freq_hz: External clock frequency, i.e. the sensor's input clock * (input) * @vt_fr: Video timing front-end configuration (output) * @vt_bk: Video timing back-end configuration (output) * @op_fr: Operational timing front-end configuration (output) * @op_bk: Operational timing back-end configuration (output) * @pixel_rate_csi: Pixel rate on the output data bus (output) * @pixel_rate_pixel_array: Nominal pixel rate in the sensor's pixel array * (output) */ struct ccs_pll { /* input values */ uint8_t bus_type; uint8_t op_lanes; uint8_t vt_lanes; struct { uint8_t lanes; } csi2; uint8_t binning_horizontal; uint8_t binning_vertical; uint8_t scale_m; uint8_t scale_n; uint8_t bits_per_pixel; uint8_t op_bits_per_lane; uint16_t flags; uint32_t link_freq; uint32_t ext_clk_freq_hz; /* output values */ struct ccs_pll_branch_fr vt_fr; struct ccs_pll_branch_bk vt_bk; struct ccs_pll_branch_fr op_fr; struct ccs_pll_branch_bk op_bk; uint32_t pixel_rate_csi; uint32_t pixel_rate_pixel_array; }; /** * struct ccs_pll_branch_limits_fr - CCS PLL front-end limits * * @min_pre_pll_clk_div: Minimum pre-PLL clock divider * @max_pre_pll_clk_div: Maximum pre-PLL clock divider * @min_pll_ip_clk_freq_hz: Minimum PLL input clock frequency * @max_pll_ip_clk_freq_hz: Maximum PLL input clock frequency * @min_pll_multiplier: Minimum PLL multiplier * @max_pll_multiplier: Maximum PLL multiplier * @min_pll_op_clk_freq_hz: Minimum PLL output clock frequency * @max_pll_op_clk_freq_hz: Maximum PLL output clock frequency */ struct ccs_pll_branch_limits_fr { uint16_t min_pre_pll_clk_div; uint16_t max_pre_pll_clk_div; uint32_t min_pll_ip_clk_freq_hz; uint32_t max_pll_ip_clk_freq_hz; uint16_t min_pll_multiplier; uint16_t max_pll_multiplier; uint32_t min_pll_op_clk_freq_hz; uint32_t max_pll_op_clk_freq_hz; }; /** * struct ccs_pll_branch_limits_bk - CCS PLL back-end limits * * @min_sys_clk_div: Minimum system clock divider * @max_sys_clk_div: Maximum system clock divider * @min_sys_clk_freq_hz: Minimum system clock frequency * @max_sys_clk_freq_hz: Maximum system clock frequency * @min_pix_clk_div: Minimum pixel clock divider * @max_pix_clk_div: Maximum pixel clock divider * @min_pix_clk_freq_hz: Minimum pixel clock frequency * @max_pix_clk_freq_hz: Maximum pixel clock frequency */ struct ccs_pll_branch_limits_bk { uint16_t min_sys_clk_div; uint16_t max_sys_clk_div; uint32_t min_sys_clk_freq_hz; uint32_t max_sys_clk_freq_hz; uint16_t min_pix_clk_div; uint16_t max_pix_clk_div; uint32_t min_pix_clk_freq_hz; uint32_t max_pix_clk_freq_hz; }; /** * struct ccs_pll_limits - CCS PLL limits * * @min_ext_clk_freq_hz: Minimum external clock frequency * @max_ext_clk_freq_hz: Maximum external clock frequency * @vt_fr: Video timing front-end limits * @vt_bk: Video timing back-end limits * @op_fr: Operational timing front-end limits * @op_bk: Operational timing back-end limits * @min_line_length_pck_bin: Minimum line length in pixels, with binning * @min_line_length_pck: Minimum line length in pixels without binning */ struct ccs_pll_limits { /* Strict PLL limits */ uint32_t min_ext_clk_freq_hz; uint32_t max_ext_clk_freq_hz; struct ccs_pll_branch_limits_fr vt_fr; struct ccs_pll_branch_limits_bk vt_bk; struct ccs_pll_branch_limits_fr op_fr; struct ccs_pll_branch_limits_bk op_bk; /* Other relevant limits */ uint32_t min_line_length_pck_bin; uint32_t min_line_length_pck; }; struct device; /** * ccs_pll_calculate - Calculate CCS PLL configuration based on input parameters * * @dev: Device pointer, used for printing messages * @limits: Limits specific to the sensor * @pll: Given PLL configuration * * Calculate the CCS PLL configuration based on the limits as well as given * device specific, system specific or user configured input data. */ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *limits, struct ccs_pll *pll); #endif /* CCS_PLL_H */