Padmanabhan Komanduru | 40f0d3c | 2018-04-26 17:41:17 +0530 | [diff] [blame] | 1 | /* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved. |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 2 | * |
| 3 | * Redistribution and use in source and binary forms, with or without |
| 4 | * modification, are permitted provided that the following conditions |
| 5 | * are met: |
| 6 | * * Redistributions of source code must retain the above copyright |
| 7 | * notice, this list of conditions and the following disclaimer. |
| 8 | * * Redistributions in binary form must reproduce the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer in |
| 10 | * the documentation and/or other materials provided with the |
| 11 | * distribution. |
| 12 | * * Neither the name of The Linux Foundation nor the names of its |
| 13 | * contributors may be used to endorse or promote products derived |
| 14 | * from this software without specific prior written permission. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 19 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 20 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 22 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| 23 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| 24 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| 26 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 27 | * SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | #include <debug.h> |
| 31 | #include <err.h> |
| 32 | #include <smem.h> |
| 33 | #include <msm_panel.h> |
| 34 | #include <mipi_dsi.h> |
| 35 | |
| 36 | #include "gcdb_autopll.h" |
| 37 | |
| 38 | static struct mdss_dsi_pll_config pll_data; |
| 39 | |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 40 | static void calculate_bitclock(struct msm_panel_info *pinfo) |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 41 | { |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 42 | uint32_t h_period = 0, v_period = 0; |
Dhaval Patel | ee8675a | 2013-10-25 10:07:57 -0700 | [diff] [blame] | 43 | uint32_t width = pinfo->xres; |
Kuogee Hsieh | e0fbc02 | 2015-07-07 10:26:58 -0700 | [diff] [blame] | 44 | struct dsc_desc *dsc = NULL; |
Kuogee Hsieh | c9ff3a7 | 2015-08-31 12:44:38 -0700 | [diff] [blame] | 45 | int bpp_lane; |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 46 | |
Dhaval Patel | ee8675a | 2013-10-25 10:07:57 -0700 | [diff] [blame] | 47 | if (pinfo->mipi.dual_dsi) |
Siddhartha Agrawal | fe64dcb | 2014-10-07 12:41:01 -0700 | [diff] [blame] | 48 | width /= 2; |
| 49 | |
Kuogee Hsieh | e0fbc02 | 2015-07-07 10:26:58 -0700 | [diff] [blame] | 50 | if (pinfo->compression_mode == COMPRESSION_DSC) { |
| 51 | dsc = &pinfo->dsc; |
| 52 | width = dsc->pclk_per_line; |
| 53 | } else if (pinfo->compression_mode == COMPRESSION_FBC) { |
| 54 | if (pinfo->fbc.comp_ratio) |
| 55 | width /= pinfo->fbc.comp_ratio; |
| 56 | } |
Dhaval Patel | ee8675a | 2013-10-25 10:07:57 -0700 | [diff] [blame] | 57 | |
| 58 | h_period = width + pinfo->lcdc.h_back_porch + |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 59 | pinfo->lcdc.h_front_porch + pinfo->lcdc.h_pulse_width + |
| 60 | pinfo->lcdc.xres_pad; |
| 61 | |
| 62 | v_period = pinfo->yres + pinfo->lcdc.v_back_porch + |
| 63 | pinfo->lcdc.v_front_porch + pinfo->lcdc.v_pulse_width + |
| 64 | pinfo->lcdc.yres_pad; |
| 65 | |
Kuogee Hsieh | c9ff3a7 | 2015-08-31 12:44:38 -0700 | [diff] [blame] | 66 | bpp_lane = pinfo->bpp / pinfo->mipi.num_of_lanes; |
| 67 | |
Aravind Venkateswaran | 3111984 | 2015-01-13 14:46:04 -0800 | [diff] [blame] | 68 | /* |
| 69 | * If a bit clock rate is not specified, calculate it based |
| 70 | * on panel parameters |
| 71 | */ |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 72 | if (pinfo->mipi.bitclock == 0) |
Aravind Venkateswaran | 3111984 | 2015-01-13 14:46:04 -0800 | [diff] [blame] | 73 | pll_data.bit_clock = (h_period * v_period * |
Kuogee Hsieh | c9ff3a7 | 2015-08-31 12:44:38 -0700 | [diff] [blame] | 74 | pinfo->mipi.frame_rate * bpp_lane); |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 75 | else |
| 76 | pll_data.bit_clock = pinfo->mipi.bitclock; |
| 77 | |
Kuogee Hsieh | c9ff3a7 | 2015-08-31 12:44:38 -0700 | [diff] [blame] | 78 | pll_data.pixel_clock = (pll_data.bit_clock / bpp_lane); |
| 79 | |
| 80 | dprintf(SPEW, "%s: bit_clk=%d pix_clk=%d\n", __func__, |
| 81 | pll_data.bit_clock, pll_data.pixel_clock); |
Aravind Venkateswaran | 3111984 | 2015-01-13 14:46:04 -0800 | [diff] [blame] | 82 | |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 83 | pll_data.byte_clock = pll_data.bit_clock >> 3; |
| 84 | |
| 85 | pll_data.halfbit_clock = pll_data.bit_clock >> 1; |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | static uint32_t calculate_div1() |
| 89 | { |
| 90 | uint32_t ret = NO_ERROR; |
| 91 | |
| 92 | /* div1 - there is divide by 2 logic present */ |
| 93 | if (pll_data.halfbit_clock > HALFBIT_CLOCK1) { |
| 94 | pll_data.posdiv1 = 0x0; /*div 1 */ |
| 95 | pll_data.vco_clock = pll_data.halfbit_clock << 1; |
| 96 | } else if (pll_data.halfbit_clock > HALFBIT_CLOCK2) { |
| 97 | pll_data.posdiv1 = 0x1; /*div 2 */ |
| 98 | pll_data.vco_clock = pll_data.halfbit_clock << 2; |
| 99 | } else if (pll_data.halfbit_clock > HALFBIT_CLOCK3) { |
| 100 | pll_data.posdiv1 = 0x3; /*div 4 */ |
| 101 | pll_data.vco_clock = pll_data.halfbit_clock << 3; |
| 102 | } else if (pll_data.halfbit_clock > HALFBIT_CLOCK4) { |
| 103 | pll_data.posdiv1 = 0x4; /*div 5 */ |
| 104 | pll_data.vco_clock = pll_data.halfbit_clock * 10; |
| 105 | } else { |
| 106 | dprintf(CRITICAL, "Not able to calculate posdiv1\n"); |
| 107 | } |
| 108 | |
| 109 | return ret; |
| 110 | } |
| 111 | |
| 112 | static uint32_t calculate_div3(uint8_t bpp, uint8_t num_of_lanes) |
| 113 | { |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 114 | pll_data.pclk_m = 0x1; /* M = 1, N= 1 */ |
| 115 | pll_data.pclk_n = 0xFF; /* ~ (N-M) = 0xff */ |
| 116 | pll_data.pclk_d = 0xFF; /* ~N = 0xFF */ |
| 117 | |
| 118 | /* formula is ( vco_clock / pdiv_digital) / mnd = pixel_clock */ |
| 119 | |
| 120 | /* div3 */ |
| 121 | switch (bpp) { |
| 122 | case BITS_18: |
| 123 | if (num_of_lanes == 3) { |
| 124 | pll_data.posdiv3 = pll_data.vco_clock / |
| 125 | pll_data.pixel_clock; |
| 126 | } else { |
| 127 | pll_data.posdiv3 = (pll_data.pixel_clock * 2 / 9) / |
| 128 | pll_data.vco_clock; |
| 129 | pll_data.pclk_m = 0x2; /* M = 2,N = 9 */ |
| 130 | pll_data.pclk_n = 0xF8; |
| 131 | pll_data.pclk_d = 0xF6; |
| 132 | } |
| 133 | break; |
| 134 | case BITS_16: |
| 135 | if (num_of_lanes == 3) { |
| 136 | pll_data.posdiv3 = (pll_data.pixel_clock * 3 / 8) / |
| 137 | pll_data.vco_clock; |
| 138 | pll_data.pclk_m = 0x3; /* M = 3, N = 9 */ |
| 139 | pll_data.pclk_n = 0xFA; |
| 140 | pll_data.pclk_d = 0xF7; |
| 141 | } else { |
| 142 | pll_data.posdiv3 = pll_data.vco_clock / |
| 143 | pll_data.pixel_clock; |
| 144 | } |
| 145 | break; |
| 146 | case BITS_24: |
| 147 | default: |
| 148 | pll_data.posdiv3 = pll_data.vco_clock / |
| 149 | pll_data.pixel_clock; |
| 150 | break; |
| 151 | } |
| 152 | |
| 153 | pll_data.posdiv3--; /* Register needs one value less */ |
Veera Sundaram Sankaran | 824e6fa | 2014-12-09 11:32:58 -0800 | [diff] [blame] | 154 | return NO_ERROR; |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 155 | } |
| 156 | |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 157 | static uint32_t calculate_dec_frac_start() |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 158 | { |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 159 | uint32_t refclk = 19200000; |
| 160 | uint32_t vco_rate = pll_data.vco_clock; |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 161 | uint32_t tmp, mod; |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 162 | |
| 163 | vco_rate /= 2; |
| 164 | pll_data.dec_start = vco_rate / refclk; |
| 165 | tmp = vco_rate % refclk; /* module, fraction */ |
| 166 | tmp /= 192; |
| 167 | tmp *= 1024; |
| 168 | tmp /= 100; |
| 169 | tmp *= 1024; |
| 170 | tmp /= 1000; |
| 171 | pll_data.frac_start = tmp; |
| 172 | |
| 173 | vco_rate *= 2; /* restore */ |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 174 | if (pll_data.en_vco_zero_phase) { |
| 175 | tmp = vco_rate / (refclk / 1000);/* div 1000 first */ |
| 176 | tmp *= 1024; |
| 177 | tmp /= 1000; |
| 178 | tmp /= 10; |
| 179 | pll_data.lock_comp = tmp - 1; |
| 180 | } else { |
| 181 | tmp = vco_rate / refclk; |
| 182 | mod = vco_rate % refclk; |
| 183 | tmp *= 127; |
| 184 | mod *= 127; |
| 185 | mod /= refclk; |
| 186 | tmp += mod; |
| 187 | tmp /= 10; |
| 188 | pll_data.lock_comp = tmp; |
| 189 | } |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 190 | |
Chandan Uddaraju | 6751956 | 2014-11-01 17:00:45 -0700 | [diff] [blame] | 191 | dprintf(SPEW, "%s: dec_start=0x%x dec_frac=0x%x lock_comp=0x%x\n", __func__, |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 192 | pll_data.dec_start, pll_data.frac_start, pll_data.lock_comp); |
Veera Sundaram Sankaran | 824e6fa | 2014-12-09 11:32:58 -0800 | [diff] [blame] | 193 | return NO_ERROR; |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | static uint32_t calculate_vco_28nm(uint8_t bpp, uint8_t num_of_lanes) |
| 197 | { |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 198 | /* If half bitclock is more than VCO min value */ |
| 199 | if (pll_data.halfbit_clock > VCO_MIN_CLOCK) { |
| 200 | |
| 201 | /* Direct Mode */ |
| 202 | |
| 203 | /* support vco clock to max value only */ |
| 204 | if (pll_data.halfbit_clock > VCO_MAX_CLOCK) |
| 205 | pll_data.vco_clock = VCO_MAX_CLOCK; |
| 206 | else |
| 207 | pll_data.vco_clock = pll_data.halfbit_clock; |
| 208 | pll_data.directpath = 0x0; |
| 209 | pll_data.posdiv1 = 0x0; /*DSI spec says 0 - div 1 */ |
| 210 | /*1 - div 2 */ |
| 211 | /*F - div 16 */ |
| 212 | } else { |
| 213 | /* Indirect Mode */ |
| 214 | |
| 215 | pll_data.directpath = 0x02; /* set bit 1 to enable for |
| 216 | indirect path */ |
| 217 | |
| 218 | calculate_div1(); |
| 219 | } |
| 220 | |
| 221 | /* calculate mnd and div3 for direct and indirect path */ |
| 222 | calculate_div3(bpp, num_of_lanes); |
| 223 | |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 224 | return NO_ERROR; |
| 225 | } |
| 226 | |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 227 | #ifndef DISPLAY_EN_20NM_PLL_90_PHASE |
| 228 | static void config_20nm_pll_vco_range(void) |
| 229 | { |
| 230 | pll_data.vco_min = 300000000; |
| 231 | pll_data.vco_max = 1500000000; |
| 232 | pll_data.en_vco_zero_phase = 1; |
| 233 | dprintf(SPEW, "%s: Configured VCO for zero phase\n", __func__); |
| 234 | } |
| 235 | #else |
| 236 | static void config_20nm_pll_vco_range(void) |
| 237 | { |
| 238 | pll_data.vco_min = 1000000000; |
| 239 | pll_data.vco_max = 2000000000; |
| 240 | pll_data.en_vco_zero_phase = 0; |
| 241 | dprintf(SPEW, "%s: Configured VCO for 90 phase\n", __func__); |
| 242 | } |
| 243 | #endif |
| 244 | |
Dhaval Patel | 236b32b | 2015-10-16 14:44:35 -0700 | [diff] [blame] | 245 | static uint32_t calculate_vco_thulium(uint8_t bpp, uint8_t lanes) |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 246 | { |
| 247 | uint32_t rate; |
| 248 | uint32_t mod; |
Dhaval Patel | 236b32b | 2015-10-16 14:44:35 -0700 | [diff] [blame] | 249 | int bpp_lane; |
| 250 | |
| 251 | /* round up the pixel clock to get the correct n2 div */ |
| 252 | bpp_lane = bpp / lanes; |
| 253 | mod = pll_data.bit_clock % bpp_lane; |
| 254 | if (mod) |
| 255 | pll_data.pixel_clock++; |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 256 | |
| 257 | pll_data.vco_min = MIN_THULIUM_VCO_RATE; |
| 258 | pll_data.vco_max = MAX_THULIUM_VCO_RATE; |
| 259 | |
| 260 | if (pll_data.bit_clock < pll_data.vco_min) |
| 261 | rate = pll_data.vco_min; |
| 262 | else if (pll_data.bit_clock > pll_data.vco_max) |
| 263 | rate = pll_data.vco_max; |
| 264 | else |
| 265 | rate = pll_data.bit_clock; |
| 266 | |
| 267 | pll_data.ndiv = FIX_N_DIV; |
| 268 | if (pll_data.bit_clock) { |
| 269 | pll_data.n1div = rate / pll_data.bit_clock; |
| 270 | } else { |
| 271 | dprintf(ERROR, "%s: bit clock is 0, divider calculation failed\n", |
| 272 | __func__); |
| 273 | return ERROR; |
| 274 | } |
| 275 | |
| 276 | mod = rate % pll_data.bit_clock; |
| 277 | if (mod) |
| 278 | pll_data.n1div++; |
| 279 | |
| 280 | if (pll_data.n1div < MIN_THULIUM_DIV_VAL || |
| 281 | pll_data.n1div > MAX_THULIUM_DIV_VAL) { |
| 282 | dprintf(ERROR, "%s: n1div is out of ranget:%d\n", |
| 283 | __func__, pll_data.n1div); |
| 284 | return ERROR; |
| 285 | } |
| 286 | |
Kuogee Hsieh | c9ff3a7 | 2015-08-31 12:44:38 -0700 | [diff] [blame] | 287 | pll_data.vco_clock = pll_data.bit_clock * pll_data.ndiv * |
| 288 | pll_data.n1div; |
| 289 | |
| 290 | rate = pll_data.vco_clock; |
| 291 | |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 292 | rate /= pll_data.n1div; |
| 293 | rate /= FIX_PIXEL_CLOCK_DIV; |
| 294 | |
| 295 | pll_data.n2div = rate / pll_data.pixel_clock; |
| 296 | mod = rate % pll_data.pixel_clock; |
| 297 | if (mod) |
| 298 | pll_data.n2div++; |
| 299 | |
| 300 | if (pll_data.n2div < MIN_THULIUM_DIV_VAL || |
| 301 | pll_data.n2div > MAX_THULIUM_DIV_VAL) { |
| 302 | dprintf(ERROR, "%s: n2div is out of ranget:%d\n", |
| 303 | __func__, pll_data.n2div); |
| 304 | return ERROR; |
| 305 | } |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 306 | |
| 307 | dprintf(SPEW, "%s: vco:%u n1div:%d n2div:%d bit_clk:%u pixel_clk:%u\n", |
| 308 | __func__, pll_data.vco_clock, pll_data.n1div, pll_data.n2div, |
| 309 | pll_data.bit_clock, pll_data.pixel_clock); |
| 310 | |
| 311 | return NO_ERROR; |
| 312 | } |
| 313 | |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 314 | static uint32_t calculate_vco_20nm(uint8_t bpp, uint8_t lanes) |
| 315 | { |
| 316 | uint32_t vco, dsi_clk; |
| 317 | int mod, ndiv, hr_oclk2, hr_oclk3; |
| 318 | int m = 1; |
| 319 | int n = 1; |
| 320 | int bpp_m = 3; /* bpp = 3 */ |
| 321 | int bpp_n = 1; |
| 322 | |
| 323 | if (bpp == BITS_18) { |
| 324 | bpp_m = 9; /* bpp = 2.25 */ |
| 325 | bpp_n = 4; |
| 326 | |
| 327 | if (lanes == 2) { |
| 328 | m = 2; |
| 329 | n = 9; |
| 330 | } else if (lanes == 4) { |
| 331 | m = 4; |
| 332 | n = 9; |
| 333 | } |
| 334 | } else if (bpp == BITS_16) { |
| 335 | bpp_m = 2; /* bpp = 2 */ |
| 336 | bpp_n = 1; |
| 337 | if (lanes == 3) { |
| 338 | m = 3; |
| 339 | n = 8; |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | hr_oclk2 = 4; |
| 344 | |
| 345 | /* If bitclock is more than VCO min value */ |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 346 | if (pll_data.halfbit_clock >= ((pll_data.vco_min) >> 1)) { |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 347 | /* Direct Mode */ |
| 348 | vco = pll_data.halfbit_clock << 1; |
| 349 | /* support vco clock to max value only */ |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 350 | if (vco > (pll_data.vco_max)) |
| 351 | vco = (pll_data.vco_max); |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 352 | |
| 353 | pll_data.directpath = 0x0; |
| 354 | pll_data.byte_clock = vco / 2 / hr_oclk2; |
| 355 | pll_data.lp_div_mux = 0x0; |
| 356 | ndiv = 1; |
| 357 | hr_oclk3 = hr_oclk2 * m / n * bpp_m / bpp_n / lanes; |
| 358 | } else { |
| 359 | /* Indirect Mode */ |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 360 | mod = (pll_data.vco_min) % (4 * pll_data.halfbit_clock ); |
| 361 | ndiv = (pll_data.vco_min) / (4 * pll_data.halfbit_clock ); |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 362 | if (mod) |
| 363 | ndiv += 1; |
| 364 | |
| 365 | vco = pll_data.halfbit_clock * 4 * ndiv; |
| 366 | pll_data.lp_div_mux = 0x1; |
| 367 | pll_data.directpath = 0x02; /* set bit 1 to enable for |
| 368 | indirect path */ |
| 369 | |
| 370 | pll_data.byte_clock = vco / 4 / hr_oclk2 / ndiv; |
| 371 | hr_oclk3 = hr_oclk2 * m / n * ndiv * 2 * bpp_m / bpp_n / lanes; |
| 372 | } |
| 373 | |
| 374 | pll_data.vco_clock = vco; |
| 375 | dsi_clk = vco / 2 / hr_oclk3; |
| 376 | pll_data.ndiv = ndiv; |
| 377 | pll_data.hr_oclk2 = hr_oclk2 - 1; /* strat from 0 */ |
| 378 | pll_data.hr_oclk3 = hr_oclk3 - 1; /* strat from 0 */ |
| 379 | |
| 380 | pll_data.pclk_m = m; /* M */ |
| 381 | pll_data.pclk_n = ~(n - m); /* ~(N-M) */ |
| 382 | pll_data.pclk_d = ~n; /* ~N */ |
| 383 | |
| 384 | dprintf(SPEW, "%s: oclk2=%d oclk3=%d ndiv=%d vco=%u dsi_clk=%u byte_clk=%u\n", |
| 385 | __func__, hr_oclk2, hr_oclk3, ndiv, vco, dsi_clk, pll_data.byte_clock); |
| 386 | |
| 387 | calculate_dec_frac_start(); |
| 388 | |
| 389 | return NO_ERROR; |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 390 | } |
| 391 | |
Padmanabhan Komanduru | 40f0d3c | 2018-04-26 17:41:17 +0530 | [diff] [blame] | 392 | static uint32_t calculate_p_div_mux(uint32_t hr_bitclk) |
| 393 | { |
| 394 | uint32_t hr_bitclk_mhz = (hr_bitclk / 1000000); |
| 395 | |
| 396 | if (hr_bitclk_mhz >= 1000 && hr_bitclk_mhz <= 1250) |
| 397 | return 0x0; |
| 398 | else if (hr_bitclk_mhz >= 500 && hr_bitclk_mhz < 1000) |
| 399 | return 0x1; |
| 400 | else if (hr_bitclk_mhz >= 250 && hr_bitclk_mhz < 500) |
| 401 | return 0x2; |
| 402 | else if (hr_bitclk_mhz >= 125 && hr_bitclk_mhz < 250) |
| 403 | return 0x3; |
| 404 | else if (hr_bitclk_mhz >= 63 && hr_bitclk_mhz < 125) |
| 405 | return 0x4; |
| 406 | else |
| 407 | return 0x5; |
| 408 | } |
| 409 | |
| 410 | static void calculate_divhf(uint32_t hr_bitclk, uint8_t bpp, |
| 411 | uint8_t lanes) |
| 412 | { |
| 413 | int m = 1; |
| 414 | int n = 1; |
| 415 | uint32_t dsi_clk = 0; |
| 416 | |
| 417 | if (bpp == BITS_18) { |
| 418 | if (lanes == 2) { |
| 419 | m = 2; |
| 420 | n = 9; |
| 421 | } else if (lanes == 4) { |
| 422 | m = 4; |
| 423 | n = 9; |
| 424 | } |
| 425 | } else if (bpp == BITS_16) { |
| 426 | if (lanes == 3) { |
| 427 | m = 3; |
| 428 | n = 8; |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | dsi_clk = (pll_data.pixel_clock * n) / m; |
| 433 | pll_data.divhf = ((pll_data.halfbit_clock / dsi_clk) - 1); |
| 434 | |
| 435 | pll_data.pclk_m = m; /* M */ |
| 436 | pll_data.pclk_n = ~(n - m); /* ~(N-M) */ |
| 437 | pll_data.pclk_d = ~n; /* ~N */ |
| 438 | } |
| 439 | |
| 440 | static uint32_t calculate_vco_12nm(uint8_t bpp, uint8_t lanes) |
| 441 | { |
| 442 | pll_data.vco_min = MIN_12NM_VCO_RATE; |
| 443 | pll_data.vco_max = MAX_12NM_VCO_RATE; |
| 444 | pll_data.p_div_mux = calculate_p_div_mux(pll_data.halfbit_clock); |
| 445 | pll_data.gp_div_mux = pll_data.p_div_mux; |
| 446 | pll_data.vco_clock = pll_data.halfbit_clock * (1 << pll_data.p_div_mux); |
| 447 | calculate_divhf(pll_data.halfbit_clock, bpp, lanes); |
| 448 | return NO_ERROR; |
| 449 | } |
| 450 | |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 451 | uint32_t calculate_clock_config(struct msm_panel_info *pinfo) |
| 452 | { |
| 453 | uint32_t ret = NO_ERROR; |
| 454 | |
| 455 | calculate_bitclock(pinfo); |
| 456 | |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 457 | switch (pinfo->mipi.mdss_dsi_phy_db->pll_type) { |
| 458 | case DSI_PLL_TYPE_20NM: |
Chandan Uddaraju | 058298e | 2015-02-04 14:25:30 -0800 | [diff] [blame] | 459 | config_20nm_pll_vco_range(); |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 460 | ret = calculate_vco_20nm(pinfo->bpp, pinfo->mipi.num_of_lanes); |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 461 | break; |
| 462 | case DSI_PLL_TYPE_THULIUM: |
| 463 | ret = calculate_vco_thulium(pinfo->bpp, pinfo->mipi.num_of_lanes); |
| 464 | break; |
Padmanabhan Komanduru | 40f0d3c | 2018-04-26 17:41:17 +0530 | [diff] [blame] | 465 | case DSI_PLL_TYPE_12NM: |
| 466 | ret = calculate_vco_12nm(pinfo->bpp, pinfo->mipi.num_of_lanes); |
| 467 | break; |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 468 | case DSI_PLL_TYPE_28NM: |
| 469 | default: |
Dhaval Patel | d19fcf1 | 2014-08-12 13:16:05 -0700 | [diff] [blame] | 470 | ret = calculate_vco_28nm(pinfo->bpp, pinfo->mipi.num_of_lanes); |
Dhaval Patel | 8b9a582 | 2015-03-16 13:01:26 -0700 | [diff] [blame] | 471 | break; |
| 472 | } |
Arpita Banerjee | da0c39a | 2013-05-24 16:12:45 -0700 | [diff] [blame] | 473 | |
| 474 | pinfo->mipi.dsi_pll_config = &pll_data; |
| 475 | |
| 476 | return ret; |
| 477 | } |