aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/ccs-pll.h
blob: b97d7ff50ea5ac8652558175785e89287b1f4672 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/* 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 <sakari.ailus@linux.intel.com>
 */

#ifndef CCS_PLL_H
#define CCS_PLL_H

#include <linux/bits.h>

/* 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 */