Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.14-rc3 460 lines 15 kB view raw
1/* 2 * drivers/media/i2c/smiapp-pll.c 3 * 4 * Generic driver for SMIA/SMIA++ compliant camera modules 5 * 6 * Copyright (C) 2011--2012 Nokia Corporation 7 * Contact: Sakari Ailus <sakari.ailus@iki.fi> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * version 2 as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 * 23 */ 24 25#include <linux/gcd.h> 26#include <linux/lcm.h> 27#include <linux/module.h> 28 29#include "smiapp-pll.h" 30 31/* Return an even number or one. */ 32static inline uint32_t clk_div_even(uint32_t a) 33{ 34 return max_t(uint32_t, 1, a & ~1); 35} 36 37/* Return an even number or one. */ 38static inline uint32_t clk_div_even_up(uint32_t a) 39{ 40 if (a == 1) 41 return 1; 42 return (a + 1) & ~1; 43} 44 45static inline uint32_t is_one_or_even(uint32_t a) 46{ 47 if (a == 1) 48 return 1; 49 if (a & 1) 50 return 0; 51 52 return 1; 53} 54 55static int bounds_check(struct device *dev, uint32_t val, 56 uint32_t min, uint32_t max, char *str) 57{ 58 if (val >= min && val <= max) 59 return 0; 60 61 dev_dbg(dev, "%s out of bounds: %d (%d--%d)\n", str, val, min, max); 62 63 return -EINVAL; 64} 65 66static void print_pll(struct device *dev, struct smiapp_pll *pll) 67{ 68 dev_dbg(dev, "pre_pll_clk_div\t%d\n", pll->pre_pll_clk_div); 69 dev_dbg(dev, "pll_multiplier \t%d\n", pll->pll_multiplier); 70 if (pll->flags != SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { 71 dev_dbg(dev, "op_sys_clk_div \t%d\n", pll->op_sys_clk_div); 72 dev_dbg(dev, "op_pix_clk_div \t%d\n", pll->op_pix_clk_div); 73 } 74 dev_dbg(dev, "vt_sys_clk_div \t%d\n", pll->vt_sys_clk_div); 75 dev_dbg(dev, "vt_pix_clk_div \t%d\n", pll->vt_pix_clk_div); 76 77 dev_dbg(dev, "ext_clk_freq_hz \t%d\n", pll->ext_clk_freq_hz); 78 dev_dbg(dev, "pll_ip_clk_freq_hz \t%d\n", pll->pll_ip_clk_freq_hz); 79 dev_dbg(dev, "pll_op_clk_freq_hz \t%d\n", pll->pll_op_clk_freq_hz); 80 if (pll->flags & SMIAPP_PLL_FLAG_NO_OP_CLOCKS) { 81 dev_dbg(dev, "op_sys_clk_freq_hz \t%d\n", 82 pll->op_sys_clk_freq_hz); 83 dev_dbg(dev, "op_pix_clk_freq_hz \t%d\n", 84 pll->op_pix_clk_freq_hz); 85 } 86 dev_dbg(dev, "vt_sys_clk_freq_hz \t%d\n", pll->vt_sys_clk_freq_hz); 87 dev_dbg(dev, "vt_pix_clk_freq_hz \t%d\n", pll->vt_pix_clk_freq_hz); 88} 89 90/* 91 * Heuristically guess the PLL tree for a given common multiplier and 92 * divisor. Begin with the operational timing and continue to video 93 * timing once operational timing has been verified. 94 * 95 * @mul is the PLL multiplier and @div is the common divisor 96 * (pre_pll_clk_div and op_sys_clk_div combined). The final PLL 97 * multiplier will be a multiple of @mul. 98 * 99 * @return Zero on success, error code on error. 100 */ 101static int __smiapp_pll_calculate(struct device *dev, 102 const struct smiapp_pll_limits *limits, 103 struct smiapp_pll *pll, uint32_t mul, 104 uint32_t div, uint32_t lane_op_clock_ratio) 105{ 106 uint32_t sys_div; 107 uint32_t best_pix_div = INT_MAX >> 1; 108 uint32_t vt_op_binning_div; 109 /* 110 * Higher multipliers (and divisors) are often required than 111 * necessitated by the external clock and the output clocks. 112 * There are limits for all values in the clock tree. These 113 * are the minimum and maximum multiplier for mul. 114 */ 115 uint32_t more_mul_min, more_mul_max; 116 uint32_t more_mul_factor; 117 uint32_t min_vt_div, max_vt_div, vt_div; 118 uint32_t min_sys_div, max_sys_div; 119 unsigned int i; 120 int rval; 121 122 /* 123 * Get pre_pll_clk_div so that our pll_op_clk_freq_hz won't be 124 * too high. 125 */ 126 dev_dbg(dev, "pre_pll_clk_div %d\n", pll->pre_pll_clk_div); 127 128 /* Don't go above max pll multiplier. */ 129 more_mul_max = limits->max_pll_multiplier / mul; 130 dev_dbg(dev, "more_mul_max: max_pll_multiplier check: %d\n", 131 more_mul_max); 132 /* Don't go above max pll op frequency. */ 133 more_mul_max = 134 min_t(uint32_t, 135 more_mul_max, 136 limits->max_pll_op_freq_hz 137 / (pll->ext_clk_freq_hz / pll->pre_pll_clk_div * mul)); 138 dev_dbg(dev, "more_mul_max: max_pll_op_freq_hz check: %d\n", 139 more_mul_max); 140 /* Don't go above the division capability of op sys clock divider. */ 141 more_mul_max = min(more_mul_max, 142 limits->op.max_sys_clk_div * pll->pre_pll_clk_div 143 / div); 144 dev_dbg(dev, "more_mul_max: max_op_sys_clk_div check: %d\n", 145 more_mul_max); 146 /* Ensure we won't go above min_pll_multiplier. */ 147 more_mul_max = min(more_mul_max, 148 DIV_ROUND_UP(limits->max_pll_multiplier, mul)); 149 dev_dbg(dev, "more_mul_max: min_pll_multiplier check: %d\n", 150 more_mul_max); 151 152 /* Ensure we won't go below min_pll_op_freq_hz. */ 153 more_mul_min = DIV_ROUND_UP(limits->min_pll_op_freq_hz, 154 pll->ext_clk_freq_hz / pll->pre_pll_clk_div 155 * mul); 156 dev_dbg(dev, "more_mul_min: min_pll_op_freq_hz check: %d\n", 157 more_mul_min); 158 /* Ensure we won't go below min_pll_multiplier. */ 159 more_mul_min = max(more_mul_min, 160 DIV_ROUND_UP(limits->min_pll_multiplier, mul)); 161 dev_dbg(dev, "more_mul_min: min_pll_multiplier check: %d\n", 162 more_mul_min); 163 164 if (more_mul_min > more_mul_max) { 165 dev_dbg(dev, 166 "unable to compute more_mul_min and more_mul_max\n"); 167 return -EINVAL; 168 } 169 170 more_mul_factor = lcm(div, pll->pre_pll_clk_div) / div; 171 dev_dbg(dev, "more_mul_factor: %d\n", more_mul_factor); 172 more_mul_factor = lcm(more_mul_factor, limits->op.min_sys_clk_div); 173 dev_dbg(dev, "more_mul_factor: min_op_sys_clk_div: %d\n", 174 more_mul_factor); 175 i = roundup(more_mul_min, more_mul_factor); 176 if (!is_one_or_even(i)) 177 i <<= 1; 178 179 dev_dbg(dev, "final more_mul: %d\n", i); 180 if (i > more_mul_max) { 181 dev_dbg(dev, "final more_mul is bad, max %d\n", more_mul_max); 182 return -EINVAL; 183 } 184 185 pll->pll_multiplier = mul * i; 186 pll->op_sys_clk_div = div * i / pll->pre_pll_clk_div; 187 dev_dbg(dev, "op_sys_clk_div: %d\n", pll->op_sys_clk_div); 188 189 pll->pll_ip_clk_freq_hz = pll->ext_clk_freq_hz 190 / pll->pre_pll_clk_div; 191 192 pll->pll_op_clk_freq_hz = pll->pll_ip_clk_freq_hz 193 * pll->pll_multiplier; 194 195 /* Derive pll_op_clk_freq_hz. */ 196 pll->op_sys_clk_freq_hz = 197 pll->pll_op_clk_freq_hz / pll->op_sys_clk_div; 198 199 pll->op_pix_clk_div = pll->bits_per_pixel; 200 dev_dbg(dev, "op_pix_clk_div: %d\n", pll->op_pix_clk_div); 201 202 pll->op_pix_clk_freq_hz = 203 pll->op_sys_clk_freq_hz / pll->op_pix_clk_div; 204 205 /* 206 * Some sensors perform analogue binning and some do this 207 * digitally. The ones doing this digitally can be roughly be 208 * found out using this formula. The ones doing this digitally 209 * should run at higher clock rate, so smaller divisor is used 210 * on video timing side. 211 */ 212 if (limits->min_line_length_pck_bin > limits->min_line_length_pck 213 / pll->binning_horizontal) 214 vt_op_binning_div = pll->binning_horizontal; 215 else 216 vt_op_binning_div = 1; 217 dev_dbg(dev, "vt_op_binning_div: %d\n", vt_op_binning_div); 218 219 /* 220 * Profile 2 supports vt_pix_clk_div E [4, 10] 221 * 222 * Horizontal binning can be used as a base for difference in 223 * divisors. One must make sure that horizontal blanking is 224 * enough to accommodate the CSI-2 sync codes. 225 * 226 * Take scaling factor into account as well. 227 * 228 * Find absolute limits for the factor of vt divider. 229 */ 230 dev_dbg(dev, "scale_m: %d\n", pll->scale_m); 231 min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div 232 * pll->scale_n, 233 lane_op_clock_ratio * vt_op_binning_div 234 * pll->scale_m); 235 236 /* Find smallest and biggest allowed vt divisor. */ 237 dev_dbg(dev, "min_vt_div: %d\n", min_vt_div); 238 min_vt_div = max(min_vt_div, 239 DIV_ROUND_UP(pll->pll_op_clk_freq_hz, 240 limits->vt.max_pix_clk_freq_hz)); 241 dev_dbg(dev, "min_vt_div: max_vt_pix_clk_freq_hz: %d\n", 242 min_vt_div); 243 min_vt_div = max_t(uint32_t, min_vt_div, 244 limits->vt.min_pix_clk_div 245 * limits->vt.min_sys_clk_div); 246 dev_dbg(dev, "min_vt_div: min_vt_clk_div: %d\n", min_vt_div); 247 248 max_vt_div = limits->vt.max_sys_clk_div * limits->vt.max_pix_clk_div; 249 dev_dbg(dev, "max_vt_div: %d\n", max_vt_div); 250 max_vt_div = min(max_vt_div, 251 DIV_ROUND_UP(pll->pll_op_clk_freq_hz, 252 limits->vt.min_pix_clk_freq_hz)); 253 dev_dbg(dev, "max_vt_div: min_vt_pix_clk_freq_hz: %d\n", 254 max_vt_div); 255 256 /* 257 * Find limitsits for sys_clk_div. Not all values are possible 258 * with all values of pix_clk_div. 259 */ 260 min_sys_div = limits->vt.min_sys_clk_div; 261 dev_dbg(dev, "min_sys_div: %d\n", min_sys_div); 262 min_sys_div = max(min_sys_div, 263 DIV_ROUND_UP(min_vt_div, 264 limits->vt.max_pix_clk_div)); 265 dev_dbg(dev, "min_sys_div: max_vt_pix_clk_div: %d\n", min_sys_div); 266 min_sys_div = max(min_sys_div, 267 pll->pll_op_clk_freq_hz 268 / limits->vt.max_sys_clk_freq_hz); 269 dev_dbg(dev, "min_sys_div: max_pll_op_clk_freq_hz: %d\n", min_sys_div); 270 min_sys_div = clk_div_even_up(min_sys_div); 271 dev_dbg(dev, "min_sys_div: one or even: %d\n", min_sys_div); 272 273 max_sys_div = limits->vt.max_sys_clk_div; 274 dev_dbg(dev, "max_sys_div: %d\n", max_sys_div); 275 max_sys_div = min(max_sys_div, 276 DIV_ROUND_UP(max_vt_div, 277 limits->vt.min_pix_clk_div)); 278 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_div: %d\n", max_sys_div); 279 max_sys_div = min(max_sys_div, 280 DIV_ROUND_UP(pll->pll_op_clk_freq_hz, 281 limits->vt.min_pix_clk_freq_hz)); 282 dev_dbg(dev, "max_sys_div: min_vt_pix_clk_freq_hz: %d\n", max_sys_div); 283 284 /* 285 * Find pix_div such that a legal pix_div * sys_div results 286 * into a value which is not smaller than div, the desired 287 * divisor. 288 */ 289 for (vt_div = min_vt_div; vt_div <= max_vt_div; 290 vt_div += 2 - (vt_div & 1)) { 291 for (sys_div = min_sys_div; 292 sys_div <= max_sys_div; 293 sys_div += 2 - (sys_div & 1)) { 294 uint16_t pix_div = DIV_ROUND_UP(vt_div, sys_div); 295 296 if (pix_div < limits->vt.min_pix_clk_div 297 || pix_div > limits->vt.max_pix_clk_div) { 298 dev_dbg(dev, 299 "pix_div %d too small or too big (%d--%d)\n", 300 pix_div, 301 limits->vt.min_pix_clk_div, 302 limits->vt.max_pix_clk_div); 303 continue; 304 } 305 306 /* Check if this one is better. */ 307 if (pix_div * sys_div 308 <= roundup(min_vt_div, best_pix_div)) 309 best_pix_div = pix_div; 310 } 311 if (best_pix_div < INT_MAX >> 1) 312 break; 313 } 314 315 pll->vt_sys_clk_div = DIV_ROUND_UP(min_vt_div, best_pix_div); 316 pll->vt_pix_clk_div = best_pix_div; 317 318 pll->vt_sys_clk_freq_hz = 319 pll->pll_op_clk_freq_hz / pll->vt_sys_clk_div; 320 pll->vt_pix_clk_freq_hz = 321 pll->vt_sys_clk_freq_hz / pll->vt_pix_clk_div; 322 323 pll->pixel_rate_csi = 324 pll->op_pix_clk_freq_hz * lane_op_clock_ratio; 325 326 rval = bounds_check(dev, pll->pll_ip_clk_freq_hz, 327 limits->min_pll_ip_freq_hz, 328 limits->max_pll_ip_freq_hz, 329 "pll_ip_clk_freq_hz"); 330 if (!rval) 331 rval = bounds_check( 332 dev, pll->pll_multiplier, 333 limits->min_pll_multiplier, limits->max_pll_multiplier, 334 "pll_multiplier"); 335 if (!rval) 336 rval = bounds_check( 337 dev, pll->pll_op_clk_freq_hz, 338 limits->min_pll_op_freq_hz, limits->max_pll_op_freq_hz, 339 "pll_op_clk_freq_hz"); 340 if (!rval) 341 rval = bounds_check( 342 dev, pll->op_sys_clk_div, 343 limits->op.min_sys_clk_div, limits->op.max_sys_clk_div, 344 "op_sys_clk_div"); 345 if (!rval) 346 rval = bounds_check( 347 dev, pll->op_pix_clk_div, 348 limits->op.min_pix_clk_div, limits->op.max_pix_clk_div, 349 "op_pix_clk_div"); 350 if (!rval) 351 rval = bounds_check( 352 dev, pll->op_sys_clk_freq_hz, 353 limits->op.min_sys_clk_freq_hz, 354 limits->op.max_sys_clk_freq_hz, 355 "op_sys_clk_freq_hz"); 356 if (!rval) 357 rval = bounds_check( 358 dev, pll->op_pix_clk_freq_hz, 359 limits->op.min_pix_clk_freq_hz, 360 limits->op.max_pix_clk_freq_hz, 361 "op_pix_clk_freq_hz"); 362 if (!rval) 363 rval = bounds_check( 364 dev, pll->vt_sys_clk_freq_hz, 365 limits->vt.min_sys_clk_freq_hz, 366 limits->vt.max_sys_clk_freq_hz, 367 "vt_sys_clk_freq_hz"); 368 if (!rval) 369 rval = bounds_check( 370 dev, pll->vt_pix_clk_freq_hz, 371 limits->vt.min_pix_clk_freq_hz, 372 limits->vt.max_pix_clk_freq_hz, 373 "vt_pix_clk_freq_hz"); 374 375 return rval; 376} 377 378int smiapp_pll_calculate(struct device *dev, 379 const struct smiapp_pll_limits *limits, 380 struct smiapp_pll *pll) 381{ 382 uint16_t min_pre_pll_clk_div; 383 uint16_t max_pre_pll_clk_div; 384 uint32_t lane_op_clock_ratio; 385 uint32_t mul, div; 386 unsigned int i; 387 int rval = -EINVAL; 388 389 if (pll->flags & SMIAPP_PLL_FLAG_OP_PIX_CLOCK_PER_LANE) 390 lane_op_clock_ratio = pll->csi2.lanes; 391 else 392 lane_op_clock_ratio = 1; 393 dev_dbg(dev, "lane_op_clock_ratio: %d\n", lane_op_clock_ratio); 394 395 dev_dbg(dev, "binning: %dx%d\n", pll->binning_horizontal, 396 pll->binning_vertical); 397 398 switch (pll->bus_type) { 399 case SMIAPP_PLL_BUS_TYPE_CSI2: 400 /* CSI transfers 2 bits per clock per lane; thus times 2 */ 401 pll->pll_op_clk_freq_hz = pll->link_freq * 2 402 * (pll->csi2.lanes / lane_op_clock_ratio); 403 break; 404 case SMIAPP_PLL_BUS_TYPE_PARALLEL: 405 pll->pll_op_clk_freq_hz = pll->link_freq * pll->bits_per_pixel 406 / DIV_ROUND_UP(pll->bits_per_pixel, 407 pll->parallel.bus_width); 408 break; 409 default: 410 return -EINVAL; 411 } 412 413 /* Figure out limits for pre-pll divider based on extclk */ 414 dev_dbg(dev, "min / max pre_pll_clk_div: %d / %d\n", 415 limits->min_pre_pll_clk_div, limits->max_pre_pll_clk_div); 416 max_pre_pll_clk_div = 417 min_t(uint16_t, limits->max_pre_pll_clk_div, 418 clk_div_even(pll->ext_clk_freq_hz / 419 limits->min_pll_ip_freq_hz)); 420 min_pre_pll_clk_div = 421 max_t(uint16_t, limits->min_pre_pll_clk_div, 422 clk_div_even_up( 423 DIV_ROUND_UP(pll->ext_clk_freq_hz, 424 limits->max_pll_ip_freq_hz))); 425 dev_dbg(dev, "pre-pll check: min / max pre_pll_clk_div: %d / %d\n", 426 min_pre_pll_clk_div, max_pre_pll_clk_div); 427 428 i = gcd(pll->pll_op_clk_freq_hz, pll->ext_clk_freq_hz); 429 mul = div_u64(pll->pll_op_clk_freq_hz, i); 430 div = pll->ext_clk_freq_hz / i; 431 dev_dbg(dev, "mul %d / div %d\n", mul, div); 432 433 min_pre_pll_clk_div = 434 max_t(uint16_t, min_pre_pll_clk_div, 435 clk_div_even_up( 436 DIV_ROUND_UP(mul * pll->ext_clk_freq_hz, 437 limits->max_pll_op_freq_hz))); 438 dev_dbg(dev, "pll_op check: min / max pre_pll_clk_div: %d / %d\n", 439 min_pre_pll_clk_div, max_pre_pll_clk_div); 440 441 for (pll->pre_pll_clk_div = min_pre_pll_clk_div; 442 pll->pre_pll_clk_div <= max_pre_pll_clk_div; 443 pll->pre_pll_clk_div += 2 - (pll->pre_pll_clk_div & 1)) { 444 rval = __smiapp_pll_calculate(dev, limits, pll, mul, div, 445 lane_op_clock_ratio); 446 if (rval) 447 continue; 448 449 print_pll(dev, pll); 450 return 0; 451 } 452 453 dev_info(dev, "unable to compute pre_pll divisor\n"); 454 return rval; 455} 456EXPORT_SYMBOL_GPL(smiapp_pll_calculate); 457 458MODULE_AUTHOR("Sakari Ailus <sakari.ailus@iki.fi>"); 459MODULE_DESCRIPTION("Generic SMIA/SMIA++ PLL calculator"); 460MODULE_LICENSE("GPL");