3840 lines · c
1/*2 * Copyright © 2006-2017 Intel Corporation3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice (including the next12 * paragraph) shall be included in all copies or substantial portions of the13 * Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21 * DEALINGS IN THE SOFTWARE.22 */23 24#include <linux/time.h>25 26#include <drm/drm_fixed.h>27 28#include "soc/intel_dram.h"29 30#include "hsw_ips.h"31#include "i915_reg.h"32#include "intel_atomic.h"33#include "intel_atomic_plane.h"34#include "intel_audio.h"35#include "intel_bw.h"36#include "intel_cdclk.h"37#include "intel_crtc.h"38#include "intel_de.h"39#include "intel_dp.h"40#include "intel_display_types.h"41#include "intel_mchbar_regs.h"42#include "intel_pci_config.h"43#include "intel_pcode.h"44#include "intel_psr.h"45#include "intel_vdsc.h"46#include "skl_watermark.h"47#include "skl_watermark_regs.h"48#include "vlv_sideband.h"49 50/**51 * DOC: CDCLK / RAWCLK52 *53 * The display engine uses several different clocks to do its work. There54 * are two main clocks involved that aren't directly related to the actual55 * pixel clock or any symbol/bit clock of the actual output port. These56 * are the core display clock (CDCLK) and RAWCLK.57 *58 * CDCLK clocks most of the display pipe logic, and thus its frequency59 * must be high enough to support the rate at which pixels are flowing60 * through the pipes. Downscaling must also be accounted as that increases61 * the effective pixel rate.62 *63 * On several platforms the CDCLK frequency can be changed dynamically64 * to minimize power consumption for a given display configuration.65 * Typically changes to the CDCLK frequency require all the display pipes66 * to be shut down while the frequency is being changed.67 *68 * On SKL+ the DMC will toggle the CDCLK off/on during DC5/6 entry/exit.69 * DMC will not change the active CDCLK frequency however, so that part70 * will still be performed by the driver directly.71 *72 * There are multiple components involved in the generation of the CDCLK73 * frequency:74 *75 * - We have the CDCLK PLL, which generates an output clock based on a76 * reference clock and a ratio parameter.77 * - The CD2X Divider, which divides the output of the PLL based on a78 * divisor selected from a set of pre-defined choices.79 * - The CD2X Squasher, which further divides the output based on a80 * waveform represented as a sequence of bits where each zero81 * "squashes out" a clock cycle.82 * - And, finally, a fixed divider that divides the output frequency by 2.83 *84 * As such, the resulting CDCLK frequency can be calculated with the85 * following formula:86 *87 * cdclk = vco / cd2x_div / (sq_len / sq_div) / 288 *89 * , where vco is the frequency generated by the PLL; cd2x_div90 * represents the CD2X Divider; sq_len and sq_div are the bit length91 * and the number of high bits for the CD2X Squasher waveform, respectively;92 * and 2 represents the fixed divider.93 *94 * Note that some older platforms do not contain the CD2X Divider95 * and/or CD2X Squasher, in which case we can ignore their respective96 * factors in the formula above.97 *98 * Several methods exist to change the CDCLK frequency, which ones are99 * supported depends on the platform:100 *101 * - Full PLL disable + re-enable with new VCO frequency. Pipes must be inactive.102 * - CD2X divider update. Single pipe can be active as the divider update103 * can be synchronized with the pipe's start of vblank.104 * - Crawl the PLL smoothly to the new VCO frequency. Pipes can be active.105 * - Squash waveform update. Pipes can be active.106 * - Crawl and squash can also be done back to back. Pipes can be active.107 *108 * RAWCLK is a fixed frequency clock, often used by various auxiliary109 * blocks such as AUX CH or backlight PWM. Hence the only thing we110 * really need to know about RAWCLK is its frequency so that various111 * dividers can be programmed correctly.112 */113 114struct intel_cdclk_funcs {115 void (*get_cdclk)(struct drm_i915_private *i915,116 struct intel_cdclk_config *cdclk_config);117 void (*set_cdclk)(struct drm_i915_private *i915,118 const struct intel_cdclk_config *cdclk_config,119 enum pipe pipe);120 int (*modeset_calc_cdclk)(struct intel_atomic_state *state);121 u8 (*calc_voltage_level)(int cdclk);122};123 124void intel_cdclk_get_cdclk(struct drm_i915_private *dev_priv,125 struct intel_cdclk_config *cdclk_config)126{127 dev_priv->display.funcs.cdclk->get_cdclk(dev_priv, cdclk_config);128}129 130static void intel_cdclk_set_cdclk(struct drm_i915_private *dev_priv,131 const struct intel_cdclk_config *cdclk_config,132 enum pipe pipe)133{134 dev_priv->display.funcs.cdclk->set_cdclk(dev_priv, cdclk_config, pipe);135}136 137static int intel_cdclk_modeset_calc_cdclk(struct intel_atomic_state *state)138{139 struct drm_i915_private *dev_priv = to_i915(state->base.dev);140 141 return dev_priv->display.funcs.cdclk->modeset_calc_cdclk(state);142}143 144static u8 intel_cdclk_calc_voltage_level(struct drm_i915_private *dev_priv,145 int cdclk)146{147 return dev_priv->display.funcs.cdclk->calc_voltage_level(cdclk);148}149 150static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv,151 struct intel_cdclk_config *cdclk_config)152{153 cdclk_config->cdclk = 133333;154}155 156static void fixed_200mhz_get_cdclk(struct drm_i915_private *dev_priv,157 struct intel_cdclk_config *cdclk_config)158{159 cdclk_config->cdclk = 200000;160}161 162static void fixed_266mhz_get_cdclk(struct drm_i915_private *dev_priv,163 struct intel_cdclk_config *cdclk_config)164{165 cdclk_config->cdclk = 266667;166}167 168static void fixed_333mhz_get_cdclk(struct drm_i915_private *dev_priv,169 struct intel_cdclk_config *cdclk_config)170{171 cdclk_config->cdclk = 333333;172}173 174static void fixed_400mhz_get_cdclk(struct drm_i915_private *dev_priv,175 struct intel_cdclk_config *cdclk_config)176{177 cdclk_config->cdclk = 400000;178}179 180static void fixed_450mhz_get_cdclk(struct drm_i915_private *dev_priv,181 struct intel_cdclk_config *cdclk_config)182{183 cdclk_config->cdclk = 450000;184}185 186static void i85x_get_cdclk(struct drm_i915_private *dev_priv,187 struct intel_cdclk_config *cdclk_config)188{189 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);190 u16 hpllcc = 0;191 192 /*193 * 852GM/852GMV only supports 133 MHz and the HPLLCC194 * encoding is different :(195 * FIXME is this the right way to detect 852GM/852GMV?196 */197 if (pdev->revision == 0x1) {198 cdclk_config->cdclk = 133333;199 return;200 }201 202 pci_bus_read_config_word(pdev->bus,203 PCI_DEVFN(0, 3), HPLLCC, &hpllcc);204 205 /* Assume that the hardware is in the high speed state. This206 * should be the default.207 */208 switch (hpllcc & GC_CLOCK_CONTROL_MASK) {209 case GC_CLOCK_133_200:210 case GC_CLOCK_133_200_2:211 case GC_CLOCK_100_200:212 cdclk_config->cdclk = 200000;213 break;214 case GC_CLOCK_166_250:215 cdclk_config->cdclk = 250000;216 break;217 case GC_CLOCK_100_133:218 cdclk_config->cdclk = 133333;219 break;220 case GC_CLOCK_133_266:221 case GC_CLOCK_133_266_2:222 case GC_CLOCK_166_266:223 cdclk_config->cdclk = 266667;224 break;225 }226}227 228static void i915gm_get_cdclk(struct drm_i915_private *dev_priv,229 struct intel_cdclk_config *cdclk_config)230{231 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);232 u16 gcfgc = 0;233 234 pci_read_config_word(pdev, GCFGC, &gcfgc);235 236 if (gcfgc & GC_LOW_FREQUENCY_ENABLE) {237 cdclk_config->cdclk = 133333;238 return;239 }240 241 switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {242 case GC_DISPLAY_CLOCK_333_320_MHZ:243 cdclk_config->cdclk = 333333;244 break;245 default:246 case GC_DISPLAY_CLOCK_190_200_MHZ:247 cdclk_config->cdclk = 190000;248 break;249 }250}251 252static void i945gm_get_cdclk(struct drm_i915_private *dev_priv,253 struct intel_cdclk_config *cdclk_config)254{255 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);256 u16 gcfgc = 0;257 258 pci_read_config_word(pdev, GCFGC, &gcfgc);259 260 if (gcfgc & GC_LOW_FREQUENCY_ENABLE) {261 cdclk_config->cdclk = 133333;262 return;263 }264 265 switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {266 case GC_DISPLAY_CLOCK_333_320_MHZ:267 cdclk_config->cdclk = 320000;268 break;269 default:270 case GC_DISPLAY_CLOCK_190_200_MHZ:271 cdclk_config->cdclk = 200000;272 break;273 }274}275 276static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)277{278 static const unsigned int blb_vco[8] = {279 [0] = 3200000,280 [1] = 4000000,281 [2] = 5333333,282 [3] = 4800000,283 [4] = 6400000,284 };285 static const unsigned int pnv_vco[8] = {286 [0] = 3200000,287 [1] = 4000000,288 [2] = 5333333,289 [3] = 4800000,290 [4] = 2666667,291 };292 static const unsigned int cl_vco[8] = {293 [0] = 3200000,294 [1] = 4000000,295 [2] = 5333333,296 [3] = 6400000,297 [4] = 3333333,298 [5] = 3566667,299 [6] = 4266667,300 };301 static const unsigned int elk_vco[8] = {302 [0] = 3200000,303 [1] = 4000000,304 [2] = 5333333,305 [3] = 4800000,306 };307 static const unsigned int ctg_vco[8] = {308 [0] = 3200000,309 [1] = 4000000,310 [2] = 5333333,311 [3] = 6400000,312 [4] = 2666667,313 [5] = 4266667,314 };315 const unsigned int *vco_table;316 unsigned int vco;317 u8 tmp = 0;318 319 /* FIXME other chipsets? */320 if (IS_GM45(dev_priv))321 vco_table = ctg_vco;322 else if (IS_G45(dev_priv))323 vco_table = elk_vco;324 else if (IS_I965GM(dev_priv))325 vco_table = cl_vco;326 else if (IS_PINEVIEW(dev_priv))327 vco_table = pnv_vco;328 else if (IS_G33(dev_priv))329 vco_table = blb_vco;330 else331 return 0;332 333 tmp = intel_de_read(dev_priv,334 IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO);335 336 vco = vco_table[tmp & 0x7];337 if (vco == 0)338 drm_err(&dev_priv->drm, "Bad HPLL VCO (HPLLVCO=0x%02x)\n",339 tmp);340 else341 drm_dbg_kms(&dev_priv->drm, "HPLL VCO %u kHz\n", vco);342 343 return vco;344}345 346static void g33_get_cdclk(struct drm_i915_private *dev_priv,347 struct intel_cdclk_config *cdclk_config)348{349 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);350 static const u8 div_3200[] = { 12, 10, 8, 7, 5, 16 };351 static const u8 div_4000[] = { 14, 12, 10, 8, 6, 20 };352 static const u8 div_4800[] = { 20, 14, 12, 10, 8, 24 };353 static const u8 div_5333[] = { 20, 16, 12, 12, 8, 28 };354 const u8 *div_table;355 unsigned int cdclk_sel;356 u16 tmp = 0;357 358 cdclk_config->vco = intel_hpll_vco(dev_priv);359 360 pci_read_config_word(pdev, GCFGC, &tmp);361 362 cdclk_sel = (tmp >> 4) & 0x7;363 364 if (cdclk_sel >= ARRAY_SIZE(div_3200))365 goto fail;366 367 switch (cdclk_config->vco) {368 case 3200000:369 div_table = div_3200;370 break;371 case 4000000:372 div_table = div_4000;373 break;374 case 4800000:375 div_table = div_4800;376 break;377 case 5333333:378 div_table = div_5333;379 break;380 default:381 goto fail;382 }383 384 cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_config->vco,385 div_table[cdclk_sel]);386 return;387 388fail:389 drm_err(&dev_priv->drm,390 "Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n",391 cdclk_config->vco, tmp);392 cdclk_config->cdclk = 190476;393}394 395static void pnv_get_cdclk(struct drm_i915_private *dev_priv,396 struct intel_cdclk_config *cdclk_config)397{398 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);399 u16 gcfgc = 0;400 401 pci_read_config_word(pdev, GCFGC, &gcfgc);402 403 switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {404 case GC_DISPLAY_CLOCK_267_MHZ_PNV:405 cdclk_config->cdclk = 266667;406 break;407 case GC_DISPLAY_CLOCK_333_MHZ_PNV:408 cdclk_config->cdclk = 333333;409 break;410 case GC_DISPLAY_CLOCK_444_MHZ_PNV:411 cdclk_config->cdclk = 444444;412 break;413 case GC_DISPLAY_CLOCK_200_MHZ_PNV:414 cdclk_config->cdclk = 200000;415 break;416 default:417 drm_err(&dev_priv->drm,418 "Unknown pnv display core clock 0x%04x\n", gcfgc);419 fallthrough;420 case GC_DISPLAY_CLOCK_133_MHZ_PNV:421 cdclk_config->cdclk = 133333;422 break;423 case GC_DISPLAY_CLOCK_167_MHZ_PNV:424 cdclk_config->cdclk = 166667;425 break;426 }427}428 429static void i965gm_get_cdclk(struct drm_i915_private *dev_priv,430 struct intel_cdclk_config *cdclk_config)431{432 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);433 static const u8 div_3200[] = { 16, 10, 8 };434 static const u8 div_4000[] = { 20, 12, 10 };435 static const u8 div_5333[] = { 24, 16, 14 };436 const u8 *div_table;437 unsigned int cdclk_sel;438 u16 tmp = 0;439 440 cdclk_config->vco = intel_hpll_vco(dev_priv);441 442 pci_read_config_word(pdev, GCFGC, &tmp);443 444 cdclk_sel = ((tmp >> 8) & 0x1f) - 1;445 446 if (cdclk_sel >= ARRAY_SIZE(div_3200))447 goto fail;448 449 switch (cdclk_config->vco) {450 case 3200000:451 div_table = div_3200;452 break;453 case 4000000:454 div_table = div_4000;455 break;456 case 5333333:457 div_table = div_5333;458 break;459 default:460 goto fail;461 }462 463 cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_config->vco,464 div_table[cdclk_sel]);465 return;466 467fail:468 drm_err(&dev_priv->drm,469 "Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n",470 cdclk_config->vco, tmp);471 cdclk_config->cdclk = 200000;472}473 474static void gm45_get_cdclk(struct drm_i915_private *dev_priv,475 struct intel_cdclk_config *cdclk_config)476{477 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);478 unsigned int cdclk_sel;479 u16 tmp = 0;480 481 cdclk_config->vco = intel_hpll_vco(dev_priv);482 483 pci_read_config_word(pdev, GCFGC, &tmp);484 485 cdclk_sel = (tmp >> 12) & 0x1;486 487 switch (cdclk_config->vco) {488 case 2666667:489 case 4000000:490 case 5333333:491 cdclk_config->cdclk = cdclk_sel ? 333333 : 222222;492 break;493 case 3200000:494 cdclk_config->cdclk = cdclk_sel ? 320000 : 228571;495 break;496 default:497 drm_err(&dev_priv->drm,498 "Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n",499 cdclk_config->vco, tmp);500 cdclk_config->cdclk = 222222;501 break;502 }503}504 505static void hsw_get_cdclk(struct drm_i915_private *dev_priv,506 struct intel_cdclk_config *cdclk_config)507{508 u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL);509 u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;510 511 if (lcpll & LCPLL_CD_SOURCE_FCLK)512 cdclk_config->cdclk = 800000;513 else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)514 cdclk_config->cdclk = 450000;515 else if (freq == LCPLL_CLK_FREQ_450)516 cdclk_config->cdclk = 450000;517 else if (IS_HASWELL_ULT(dev_priv))518 cdclk_config->cdclk = 337500;519 else520 cdclk_config->cdclk = 540000;521}522 523static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)524{525 int freq_320 = (dev_priv->hpll_freq << 1) % 320000 != 0 ?526 333333 : 320000;527 528 /*529 * We seem to get an unstable or solid color picture at 200MHz.530 * Not sure what's wrong. For now use 200MHz only when all pipes531 * are off.532 */533 if (IS_VALLEYVIEW(dev_priv) && min_cdclk > freq_320)534 return 400000;535 else if (min_cdclk > 266667)536 return freq_320;537 else if (min_cdclk > 0)538 return 266667;539 else540 return 200000;541}542 543static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk)544{545 if (IS_VALLEYVIEW(dev_priv)) {546 if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */547 return 2;548 else if (cdclk >= 266667)549 return 1;550 else551 return 0;552 } else {553 /*554 * Specs are full of misinformation, but testing on actual555 * hardware has shown that we just need to write the desired556 * CCK divider into the Punit register.557 */558 return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;559 }560}561 562static void vlv_get_cdclk(struct drm_i915_private *dev_priv,563 struct intel_cdclk_config *cdclk_config)564{565 u32 val;566 567 vlv_iosf_sb_get(dev_priv,568 BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));569 570 cdclk_config->vco = vlv_get_hpll_vco(dev_priv);571 cdclk_config->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",572 CCK_DISPLAY_CLOCK_CONTROL,573 cdclk_config->vco);574 575 val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);576 577 vlv_iosf_sb_put(dev_priv,578 BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));579 580 if (IS_VALLEYVIEW(dev_priv))581 cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK) >>582 DSPFREQGUAR_SHIFT;583 else584 cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK_CHV) >>585 DSPFREQGUAR_SHIFT_CHV;586}587 588static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)589{590 unsigned int credits, default_credits;591 592 if (IS_CHERRYVIEW(dev_priv))593 default_credits = PFI_CREDIT(12);594 else595 default_credits = PFI_CREDIT(8);596 597 if (dev_priv->display.cdclk.hw.cdclk >= dev_priv->czclk_freq) {598 /* CHV suggested value is 31 or 63 */599 if (IS_CHERRYVIEW(dev_priv))600 credits = PFI_CREDIT_63;601 else602 credits = PFI_CREDIT(15);603 } else {604 credits = default_credits;605 }606 607 /*608 * WA - write default credits before re-programming609 * FIXME: should we also set the resend bit here?610 */611 intel_de_write(dev_priv, GCI_CONTROL,612 VGA_FAST_MODE_DISABLE | default_credits);613 614 intel_de_write(dev_priv, GCI_CONTROL,615 VGA_FAST_MODE_DISABLE | credits | PFI_CREDIT_RESEND);616 617 /*618 * FIXME is this guaranteed to clear619 * immediately or should we poll for it?620 */621 drm_WARN_ON(&dev_priv->drm,622 intel_de_read(dev_priv, GCI_CONTROL) & PFI_CREDIT_RESEND);623}624 625static void vlv_set_cdclk(struct drm_i915_private *dev_priv,626 const struct intel_cdclk_config *cdclk_config,627 enum pipe pipe)628{629 int cdclk = cdclk_config->cdclk;630 u32 val, cmd = cdclk_config->voltage_level;631 intel_wakeref_t wakeref;632 633 switch (cdclk) {634 case 400000:635 case 333333:636 case 320000:637 case 266667:638 case 200000:639 break;640 default:641 MISSING_CASE(cdclk);642 return;643 }644 645 /* There are cases where we can end up here with power domains646 * off and a CDCLK frequency other than the minimum, like when647 * issuing a modeset without actually changing any display after648 * a system suspend. So grab the display core domain, which covers649 * the HW blocks needed for the following programming.650 */651 wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);652 653 vlv_iosf_sb_get(dev_priv,654 BIT(VLV_IOSF_SB_CCK) |655 BIT(VLV_IOSF_SB_BUNIT) |656 BIT(VLV_IOSF_SB_PUNIT));657 658 val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);659 val &= ~DSPFREQGUAR_MASK;660 val |= (cmd << DSPFREQGUAR_SHIFT);661 vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);662 if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &663 DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),664 50)) {665 drm_err(&dev_priv->drm,666 "timed out waiting for CDclk change\n");667 }668 669 if (cdclk == 400000) {670 u32 divider;671 672 divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1,673 cdclk) - 1;674 675 /* adjust cdclk divider */676 val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);677 val &= ~CCK_FREQUENCY_VALUES;678 val |= divider;679 vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);680 681 if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &682 CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),683 50))684 drm_err(&dev_priv->drm,685 "timed out waiting for CDclk change\n");686 }687 688 /* adjust self-refresh exit latency value */689 val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);690 val &= ~0x7f;691 692 /*693 * For high bandwidth configs, we set a higher latency in the bunit694 * so that the core display fetch happens in time to avoid underruns.695 */696 if (cdclk == 400000)697 val |= 4500 / 250; /* 4.5 usec */698 else699 val |= 3000 / 250; /* 3.0 usec */700 vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);701 702 vlv_iosf_sb_put(dev_priv,703 BIT(VLV_IOSF_SB_CCK) |704 BIT(VLV_IOSF_SB_BUNIT) |705 BIT(VLV_IOSF_SB_PUNIT));706 707 intel_update_cdclk(dev_priv);708 709 vlv_program_pfi_credits(dev_priv);710 711 intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);712}713 714static void chv_set_cdclk(struct drm_i915_private *dev_priv,715 const struct intel_cdclk_config *cdclk_config,716 enum pipe pipe)717{718 int cdclk = cdclk_config->cdclk;719 u32 val, cmd = cdclk_config->voltage_level;720 intel_wakeref_t wakeref;721 722 switch (cdclk) {723 case 333333:724 case 320000:725 case 266667:726 case 200000:727 break;728 default:729 MISSING_CASE(cdclk);730 return;731 }732 733 /* There are cases where we can end up here with power domains734 * off and a CDCLK frequency other than the minimum, like when735 * issuing a modeset without actually changing any display after736 * a system suspend. So grab the display core domain, which covers737 * the HW blocks needed for the following programming.738 */739 wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);740 741 vlv_punit_get(dev_priv);742 val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);743 val &= ~DSPFREQGUAR_MASK_CHV;744 val |= (cmd << DSPFREQGUAR_SHIFT_CHV);745 vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);746 if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &747 DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),748 50)) {749 drm_err(&dev_priv->drm,750 "timed out waiting for CDclk change\n");751 }752 753 vlv_punit_put(dev_priv);754 755 intel_update_cdclk(dev_priv);756 757 vlv_program_pfi_credits(dev_priv);758 759 intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);760}761 762static int bdw_calc_cdclk(int min_cdclk)763{764 if (min_cdclk > 540000)765 return 675000;766 else if (min_cdclk > 450000)767 return 540000;768 else if (min_cdclk > 337500)769 return 450000;770 else771 return 337500;772}773 774static u8 bdw_calc_voltage_level(int cdclk)775{776 switch (cdclk) {777 default:778 case 337500:779 return 2;780 case 450000:781 return 0;782 case 540000:783 return 1;784 case 675000:785 return 3;786 }787}788 789static void bdw_get_cdclk(struct drm_i915_private *dev_priv,790 struct intel_cdclk_config *cdclk_config)791{792 u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL);793 u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;794 795 if (lcpll & LCPLL_CD_SOURCE_FCLK)796 cdclk_config->cdclk = 800000;797 else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)798 cdclk_config->cdclk = 450000;799 else if (freq == LCPLL_CLK_FREQ_450)800 cdclk_config->cdclk = 450000;801 else if (freq == LCPLL_CLK_FREQ_54O_BDW)802 cdclk_config->cdclk = 540000;803 else if (freq == LCPLL_CLK_FREQ_337_5_BDW)804 cdclk_config->cdclk = 337500;805 else806 cdclk_config->cdclk = 675000;807 808 /*809 * Can't read this out :( Let's assume it's810 * at least what the CDCLK frequency requires.811 */812 cdclk_config->voltage_level =813 bdw_calc_voltage_level(cdclk_config->cdclk);814}815 816static u32 bdw_cdclk_freq_sel(int cdclk)817{818 switch (cdclk) {819 default:820 MISSING_CASE(cdclk);821 fallthrough;822 case 337500:823 return LCPLL_CLK_FREQ_337_5_BDW;824 case 450000:825 return LCPLL_CLK_FREQ_450;826 case 540000:827 return LCPLL_CLK_FREQ_54O_BDW;828 case 675000:829 return LCPLL_CLK_FREQ_675_BDW;830 }831}832 833static void bdw_set_cdclk(struct drm_i915_private *dev_priv,834 const struct intel_cdclk_config *cdclk_config,835 enum pipe pipe)836{837 int cdclk = cdclk_config->cdclk;838 int ret;839 840 if (drm_WARN(&dev_priv->drm,841 (intel_de_read(dev_priv, LCPLL_CTL) &842 (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |843 LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |844 LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |845 LCPLL_CD_SOURCE_FCLK)) != LCPLL_PLL_LOCK,846 "trying to change cdclk frequency with cdclk not enabled\n"))847 return;848 849 ret = snb_pcode_write(&dev_priv->uncore, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);850 if (ret) {851 drm_err(&dev_priv->drm,852 "failed to inform pcode about cdclk change\n");853 return;854 }855 856 intel_de_rmw(dev_priv, LCPLL_CTL,857 0, LCPLL_CD_SOURCE_FCLK);858 859 /*860 * According to the spec, it should be enough to poll for this 1 us.861 * However, extensive testing shows that this can take longer.862 */863 if (wait_for_us(intel_de_read(dev_priv, LCPLL_CTL) &864 LCPLL_CD_SOURCE_FCLK_DONE, 100))865 drm_err(&dev_priv->drm, "Switching to FCLK failed\n");866 867 intel_de_rmw(dev_priv, LCPLL_CTL,868 LCPLL_CLK_FREQ_MASK, bdw_cdclk_freq_sel(cdclk));869 870 intel_de_rmw(dev_priv, LCPLL_CTL,871 LCPLL_CD_SOURCE_FCLK, 0);872 873 if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) &874 LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))875 drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n");876 877 snb_pcode_write(&dev_priv->uncore, HSW_PCODE_DE_WRITE_FREQ_REQ,878 cdclk_config->voltage_level);879 880 intel_de_write(dev_priv, CDCLK_FREQ,881 DIV_ROUND_CLOSEST(cdclk, 1000) - 1);882 883 intel_update_cdclk(dev_priv);884}885 886static int skl_calc_cdclk(int min_cdclk, int vco)887{888 if (vco == 8640000) {889 if (min_cdclk > 540000)890 return 617143;891 else if (min_cdclk > 432000)892 return 540000;893 else if (min_cdclk > 308571)894 return 432000;895 else896 return 308571;897 } else {898 if (min_cdclk > 540000)899 return 675000;900 else if (min_cdclk > 450000)901 return 540000;902 else if (min_cdclk > 337500)903 return 450000;904 else905 return 337500;906 }907}908 909static u8 skl_calc_voltage_level(int cdclk)910{911 if (cdclk > 540000)912 return 3;913 else if (cdclk > 450000)914 return 2;915 else if (cdclk > 337500)916 return 1;917 else918 return 0;919}920 921static void skl_dpll0_update(struct drm_i915_private *dev_priv,922 struct intel_cdclk_config *cdclk_config)923{924 u32 val;925 926 cdclk_config->ref = 24000;927 cdclk_config->vco = 0;928 929 val = intel_de_read(dev_priv, LCPLL1_CTL);930 if ((val & LCPLL_PLL_ENABLE) == 0)931 return;932 933 if (drm_WARN_ON(&dev_priv->drm, (val & LCPLL_PLL_LOCK) == 0))934 return;935 936 val = intel_de_read(dev_priv, DPLL_CTRL1);937 938 if (drm_WARN_ON(&dev_priv->drm,939 (val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |940 DPLL_CTRL1_SSC(SKL_DPLL0) |941 DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) !=942 DPLL_CTRL1_OVERRIDE(SKL_DPLL0)))943 return;944 945 switch (val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) {946 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0):947 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, SKL_DPLL0):948 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, SKL_DPLL0):949 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, SKL_DPLL0):950 cdclk_config->vco = 8100000;951 break;952 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0):953 case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, SKL_DPLL0):954 cdclk_config->vco = 8640000;955 break;956 default:957 MISSING_CASE(val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));958 break;959 }960}961 962static void skl_get_cdclk(struct drm_i915_private *dev_priv,963 struct intel_cdclk_config *cdclk_config)964{965 u32 cdctl;966 967 skl_dpll0_update(dev_priv, cdclk_config);968 969 cdclk_config->cdclk = cdclk_config->bypass = cdclk_config->ref;970 971 if (cdclk_config->vco == 0)972 goto out;973 974 cdctl = intel_de_read(dev_priv, CDCLK_CTL);975 976 if (cdclk_config->vco == 8640000) {977 switch (cdctl & CDCLK_FREQ_SEL_MASK) {978 case CDCLK_FREQ_450_432:979 cdclk_config->cdclk = 432000;980 break;981 case CDCLK_FREQ_337_308:982 cdclk_config->cdclk = 308571;983 break;984 case CDCLK_FREQ_540:985 cdclk_config->cdclk = 540000;986 break;987 case CDCLK_FREQ_675_617:988 cdclk_config->cdclk = 617143;989 break;990 default:991 MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);992 break;993 }994 } else {995 switch (cdctl & CDCLK_FREQ_SEL_MASK) {996 case CDCLK_FREQ_450_432:997 cdclk_config->cdclk = 450000;998 break;999 case CDCLK_FREQ_337_308:1000 cdclk_config->cdclk = 337500;1001 break;1002 case CDCLK_FREQ_540:1003 cdclk_config->cdclk = 540000;1004 break;1005 case CDCLK_FREQ_675_617:1006 cdclk_config->cdclk = 675000;1007 break;1008 default:1009 MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);1010 break;1011 }1012 }1013 1014 out:1015 /*1016 * Can't read this out :( Let's assume it's1017 * at least what the CDCLK frequency requires.1018 */1019 cdclk_config->voltage_level =1020 skl_calc_voltage_level(cdclk_config->cdclk);1021}1022 1023/* convert from kHz to .1 fixpoint MHz with -1MHz offset */1024static int skl_cdclk_decimal(int cdclk)1025{1026 return DIV_ROUND_CLOSEST(cdclk - 1000, 500);1027}1028 1029static void skl_set_preferred_cdclk_vco(struct drm_i915_private *i915, int vco)1030{1031 bool changed = i915->display.cdclk.skl_preferred_vco_freq != vco;1032 1033 i915->display.cdclk.skl_preferred_vco_freq = vco;1034 1035 if (changed)1036 intel_update_max_cdclk(i915);1037}1038 1039static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco)1040{1041 drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);1042 1043 /*1044 * We always enable DPLL0 with the lowest link rate possible, but still1045 * taking into account the VCO required to operate the eDP panel at the1046 * desired frequency. The usual DP link rates operate with a VCO of1047 * 8100 while the eDP 1.4 alternate link rates need a VCO of 8640.1048 * The modeset code is responsible for the selection of the exact link1049 * rate later on, with the constraint of choosing a frequency that1050 * works with vco.1051 */1052 if (vco == 8640000)1053 return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0);1054 else1055 return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0);1056}1057 1058static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)1059{1060 intel_de_rmw(dev_priv, DPLL_CTRL1,1061 DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |1062 DPLL_CTRL1_SSC(SKL_DPLL0) |1063 DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0),1064 DPLL_CTRL1_OVERRIDE(SKL_DPLL0) |1065 skl_dpll0_link_rate(dev_priv, vco));1066 intel_de_posting_read(dev_priv, DPLL_CTRL1);1067 1068 intel_de_rmw(dev_priv, LCPLL1_CTL,1069 0, LCPLL_PLL_ENABLE);1070 1071 if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))1072 drm_err(&dev_priv->drm, "DPLL0 not locked\n");1073 1074 dev_priv->display.cdclk.hw.vco = vco;1075 1076 /* We'll want to keep using the current vco from now on. */1077 skl_set_preferred_cdclk_vco(dev_priv, vco);1078}1079 1080static void skl_dpll0_disable(struct drm_i915_private *dev_priv)1081{1082 intel_de_rmw(dev_priv, LCPLL1_CTL,1083 LCPLL_PLL_ENABLE, 0);1084 1085 if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))1086 drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n");1087 1088 dev_priv->display.cdclk.hw.vco = 0;1089}1090 1091static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,1092 int cdclk, int vco)1093{1094 switch (cdclk) {1095 default:1096 drm_WARN_ON(&dev_priv->drm,1097 cdclk != dev_priv->display.cdclk.hw.bypass);1098 drm_WARN_ON(&dev_priv->drm, vco != 0);1099 fallthrough;1100 case 308571:1101 case 337500:1102 return CDCLK_FREQ_337_308;1103 case 450000:1104 case 432000:1105 return CDCLK_FREQ_450_432;1106 case 540000:1107 return CDCLK_FREQ_540;1108 case 617143:1109 case 675000:1110 return CDCLK_FREQ_675_617;1111 }1112}1113 1114static void skl_set_cdclk(struct drm_i915_private *dev_priv,1115 const struct intel_cdclk_config *cdclk_config,1116 enum pipe pipe)1117{1118 int cdclk = cdclk_config->cdclk;1119 int vco = cdclk_config->vco;1120 u32 freq_select, cdclk_ctl;1121 int ret;1122 1123 /*1124 * Based on WA#1183 CDCLK rates 308 and 617MHz CDCLK rates are1125 * unsupported on SKL. In theory this should never happen since only1126 * the eDP1.4 2.16 and 4.32Gbps rates require it, but eDP1.4 is not1127 * supported on SKL either, see the above WA. WARN whenever trying to1128 * use the corresponding VCO freq as that always leads to using the1129 * minimum 308MHz CDCLK.1130 */1131 drm_WARN_ON_ONCE(&dev_priv->drm,1132 IS_SKYLAKE(dev_priv) && vco == 8640000);1133 1134 ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,1135 SKL_CDCLK_PREPARE_FOR_CHANGE,1136 SKL_CDCLK_READY_FOR_CHANGE,1137 SKL_CDCLK_READY_FOR_CHANGE, 3);1138 if (ret) {1139 drm_err(&dev_priv->drm,1140 "Failed to inform PCU about cdclk change (%d)\n", ret);1141 return;1142 }1143 1144 freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco);1145 1146 if (dev_priv->display.cdclk.hw.vco != 0 &&1147 dev_priv->display.cdclk.hw.vco != vco)1148 skl_dpll0_disable(dev_priv);1149 1150 cdclk_ctl = intel_de_read(dev_priv, CDCLK_CTL);1151 1152 if (dev_priv->display.cdclk.hw.vco != vco) {1153 /* Wa Display #1183: skl,kbl,cfl */1154 cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);1155 cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);1156 intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);1157 }1158 1159 /* Wa Display #1183: skl,kbl,cfl */1160 cdclk_ctl |= CDCLK_DIVMUX_CD_OVERRIDE;1161 intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);1162 intel_de_posting_read(dev_priv, CDCLK_CTL);1163 1164 if (dev_priv->display.cdclk.hw.vco != vco)1165 skl_dpll0_enable(dev_priv, vco);1166 1167 /* Wa Display #1183: skl,kbl,cfl */1168 cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);1169 intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);1170 1171 cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);1172 intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);1173 1174 /* Wa Display #1183: skl,kbl,cfl */1175 cdclk_ctl &= ~CDCLK_DIVMUX_CD_OVERRIDE;1176 intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);1177 intel_de_posting_read(dev_priv, CDCLK_CTL);1178 1179 /* inform PCU of the change */1180 snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,1181 cdclk_config->voltage_level);1182 1183 intel_update_cdclk(dev_priv);1184}1185 1186static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)1187{1188 u32 cdctl, expected;1189 1190 /*1191 * check if the pre-os initialized the display1192 * There is SWF18 scratchpad register defined which is set by the1193 * pre-os which can be used by the OS drivers to check the status1194 */1195 if ((intel_de_read(dev_priv, SWF_ILK(0x18)) & 0x00FFFFFF) == 0)1196 goto sanitize;1197 1198 intel_update_cdclk(dev_priv);1199 intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");1200 1201 /* Is PLL enabled and locked ? */1202 if (dev_priv->display.cdclk.hw.vco == 0 ||1203 dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass)1204 goto sanitize;1205 1206 /* DPLL okay; verify the cdclock1207 *1208 * Noticed in some instances that the freq selection is correct but1209 * decimal part is programmed wrong from BIOS where pre-os does not1210 * enable display. Verify the same as well.1211 */1212 cdctl = intel_de_read(dev_priv, CDCLK_CTL);1213 expected = (cdctl & CDCLK_FREQ_SEL_MASK) |1214 skl_cdclk_decimal(dev_priv->display.cdclk.hw.cdclk);1215 if (cdctl == expected)1216 /* All well; nothing to sanitize */1217 return;1218 1219sanitize:1220 drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");1221 1222 /* force cdclk programming */1223 dev_priv->display.cdclk.hw.cdclk = 0;1224 /* force full PLL disable + enable */1225 dev_priv->display.cdclk.hw.vco = ~0;1226}1227 1228static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv)1229{1230 struct intel_cdclk_config cdclk_config;1231 1232 skl_sanitize_cdclk(dev_priv);1233 1234 if (dev_priv->display.cdclk.hw.cdclk != 0 &&1235 dev_priv->display.cdclk.hw.vco != 0) {1236 /*1237 * Use the current vco as our initial1238 * guess as to what the preferred vco is.1239 */1240 if (dev_priv->display.cdclk.skl_preferred_vco_freq == 0)1241 skl_set_preferred_cdclk_vco(dev_priv,1242 dev_priv->display.cdclk.hw.vco);1243 return;1244 }1245 1246 cdclk_config = dev_priv->display.cdclk.hw;1247 1248 cdclk_config.vco = dev_priv->display.cdclk.skl_preferred_vco_freq;1249 if (cdclk_config.vco == 0)1250 cdclk_config.vco = 8100000;1251 cdclk_config.cdclk = skl_calc_cdclk(0, cdclk_config.vco);1252 cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk);1253 1254 skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);1255}1256 1257static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv)1258{1259 struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw;1260 1261 cdclk_config.cdclk = cdclk_config.bypass;1262 cdclk_config.vco = 0;1263 cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk);1264 1265 skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);1266}1267 1268struct intel_cdclk_vals {1269 u32 cdclk;1270 u16 refclk;1271 u16 waveform;1272 u8 ratio;1273};1274 1275static const struct intel_cdclk_vals bxt_cdclk_table[] = {1276 { .refclk = 19200, .cdclk = 144000, .ratio = 60 },1277 { .refclk = 19200, .cdclk = 288000, .ratio = 60 },1278 { .refclk = 19200, .cdclk = 384000, .ratio = 60 },1279 { .refclk = 19200, .cdclk = 576000, .ratio = 60 },1280 { .refclk = 19200, .cdclk = 624000, .ratio = 65 },1281 {}1282};1283 1284static const struct intel_cdclk_vals glk_cdclk_table[] = {1285 { .refclk = 19200, .cdclk = 79200, .ratio = 33 },1286 { .refclk = 19200, .cdclk = 158400, .ratio = 33 },1287 { .refclk = 19200, .cdclk = 316800, .ratio = 33 },1288 {}1289};1290 1291static const struct intel_cdclk_vals icl_cdclk_table[] = {1292 { .refclk = 19200, .cdclk = 172800, .ratio = 18 },1293 { .refclk = 19200, .cdclk = 192000, .ratio = 20 },1294 { .refclk = 19200, .cdclk = 307200, .ratio = 32 },1295 { .refclk = 19200, .cdclk = 326400, .ratio = 68 },1296 { .refclk = 19200, .cdclk = 556800, .ratio = 58 },1297 { .refclk = 19200, .cdclk = 652800, .ratio = 68 },1298 1299 { .refclk = 24000, .cdclk = 180000, .ratio = 15 },1300 { .refclk = 24000, .cdclk = 192000, .ratio = 16 },1301 { .refclk = 24000, .cdclk = 312000, .ratio = 26 },1302 { .refclk = 24000, .cdclk = 324000, .ratio = 54 },1303 { .refclk = 24000, .cdclk = 552000, .ratio = 46 },1304 { .refclk = 24000, .cdclk = 648000, .ratio = 54 },1305 1306 { .refclk = 38400, .cdclk = 172800, .ratio = 9 },1307 { .refclk = 38400, .cdclk = 192000, .ratio = 10 },1308 { .refclk = 38400, .cdclk = 307200, .ratio = 16 },1309 { .refclk = 38400, .cdclk = 326400, .ratio = 34 },1310 { .refclk = 38400, .cdclk = 556800, .ratio = 29 },1311 { .refclk = 38400, .cdclk = 652800, .ratio = 34 },1312 {}1313};1314 1315static const struct intel_cdclk_vals rkl_cdclk_table[] = {1316 { .refclk = 19200, .cdclk = 172800, .ratio = 36 },1317 { .refclk = 19200, .cdclk = 192000, .ratio = 40 },1318 { .refclk = 19200, .cdclk = 307200, .ratio = 64 },1319 { .refclk = 19200, .cdclk = 326400, .ratio = 136 },1320 { .refclk = 19200, .cdclk = 556800, .ratio = 116 },1321 { .refclk = 19200, .cdclk = 652800, .ratio = 136 },1322 1323 { .refclk = 24000, .cdclk = 180000, .ratio = 30 },1324 { .refclk = 24000, .cdclk = 192000, .ratio = 32 },1325 { .refclk = 24000, .cdclk = 312000, .ratio = 52 },1326 { .refclk = 24000, .cdclk = 324000, .ratio = 108 },1327 { .refclk = 24000, .cdclk = 552000, .ratio = 92 },1328 { .refclk = 24000, .cdclk = 648000, .ratio = 108 },1329 1330 { .refclk = 38400, .cdclk = 172800, .ratio = 18 },1331 { .refclk = 38400, .cdclk = 192000, .ratio = 20 },1332 { .refclk = 38400, .cdclk = 307200, .ratio = 32 },1333 { .refclk = 38400, .cdclk = 326400, .ratio = 68 },1334 { .refclk = 38400, .cdclk = 556800, .ratio = 58 },1335 { .refclk = 38400, .cdclk = 652800, .ratio = 68 },1336 {}1337};1338 1339static const struct intel_cdclk_vals adlp_a_step_cdclk_table[] = {1340 { .refclk = 19200, .cdclk = 307200, .ratio = 32 },1341 { .refclk = 19200, .cdclk = 556800, .ratio = 58 },1342 { .refclk = 19200, .cdclk = 652800, .ratio = 68 },1343 1344 { .refclk = 24000, .cdclk = 312000, .ratio = 26 },1345 { .refclk = 24000, .cdclk = 552000, .ratio = 46 },1346 { .refclk = 24400, .cdclk = 648000, .ratio = 54 },1347 1348 { .refclk = 38400, .cdclk = 307200, .ratio = 16 },1349 { .refclk = 38400, .cdclk = 556800, .ratio = 29 },1350 { .refclk = 38400, .cdclk = 652800, .ratio = 34 },1351 {}1352};1353 1354static const struct intel_cdclk_vals adlp_cdclk_table[] = {1355 { .refclk = 19200, .cdclk = 172800, .ratio = 27 },1356 { .refclk = 19200, .cdclk = 192000, .ratio = 20 },1357 { .refclk = 19200, .cdclk = 307200, .ratio = 32 },1358 { .refclk = 19200, .cdclk = 556800, .ratio = 58 },1359 { .refclk = 19200, .cdclk = 652800, .ratio = 68 },1360 1361 { .refclk = 24000, .cdclk = 176000, .ratio = 22 },1362 { .refclk = 24000, .cdclk = 192000, .ratio = 16 },1363 { .refclk = 24000, .cdclk = 312000, .ratio = 26 },1364 { .refclk = 24000, .cdclk = 552000, .ratio = 46 },1365 { .refclk = 24000, .cdclk = 648000, .ratio = 54 },1366 1367 { .refclk = 38400, .cdclk = 179200, .ratio = 14 },1368 { .refclk = 38400, .cdclk = 192000, .ratio = 10 },1369 { .refclk = 38400, .cdclk = 307200, .ratio = 16 },1370 { .refclk = 38400, .cdclk = 556800, .ratio = 29 },1371 { .refclk = 38400, .cdclk = 652800, .ratio = 34 },1372 {}1373};1374 1375static const struct intel_cdclk_vals rplu_cdclk_table[] = {1376 { .refclk = 19200, .cdclk = 172800, .ratio = 27 },1377 { .refclk = 19200, .cdclk = 192000, .ratio = 20 },1378 { .refclk = 19200, .cdclk = 307200, .ratio = 32 },1379 { .refclk = 19200, .cdclk = 480000, .ratio = 50 },1380 { .refclk = 19200, .cdclk = 556800, .ratio = 58 },1381 { .refclk = 19200, .cdclk = 652800, .ratio = 68 },1382 1383 { .refclk = 24000, .cdclk = 176000, .ratio = 22 },1384 { .refclk = 24000, .cdclk = 192000, .ratio = 16 },1385 { .refclk = 24000, .cdclk = 312000, .ratio = 26 },1386 { .refclk = 24000, .cdclk = 480000, .ratio = 40 },1387 { .refclk = 24000, .cdclk = 552000, .ratio = 46 },1388 { .refclk = 24000, .cdclk = 648000, .ratio = 54 },1389 1390 { .refclk = 38400, .cdclk = 179200, .ratio = 14 },1391 { .refclk = 38400, .cdclk = 192000, .ratio = 10 },1392 { .refclk = 38400, .cdclk = 307200, .ratio = 16 },1393 { .refclk = 38400, .cdclk = 480000, .ratio = 25 },1394 { .refclk = 38400, .cdclk = 556800, .ratio = 29 },1395 { .refclk = 38400, .cdclk = 652800, .ratio = 34 },1396 {}1397};1398 1399static const struct intel_cdclk_vals dg2_cdclk_table[] = {1400 { .refclk = 38400, .cdclk = 163200, .ratio = 34, .waveform = 0x8888 },1401 { .refclk = 38400, .cdclk = 204000, .ratio = 34, .waveform = 0x9248 },1402 { .refclk = 38400, .cdclk = 244800, .ratio = 34, .waveform = 0xa4a4 },1403 { .refclk = 38400, .cdclk = 285600, .ratio = 34, .waveform = 0xa54a },1404 { .refclk = 38400, .cdclk = 326400, .ratio = 34, .waveform = 0xaaaa },1405 { .refclk = 38400, .cdclk = 367200, .ratio = 34, .waveform = 0xad5a },1406 { .refclk = 38400, .cdclk = 408000, .ratio = 34, .waveform = 0xb6b6 },1407 { .refclk = 38400, .cdclk = 448800, .ratio = 34, .waveform = 0xdbb6 },1408 { .refclk = 38400, .cdclk = 489600, .ratio = 34, .waveform = 0xeeee },1409 { .refclk = 38400, .cdclk = 530400, .ratio = 34, .waveform = 0xf7de },1410 { .refclk = 38400, .cdclk = 571200, .ratio = 34, .waveform = 0xfefe },1411 { .refclk = 38400, .cdclk = 612000, .ratio = 34, .waveform = 0xfffe },1412 { .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },1413 {}1414};1415 1416static const struct intel_cdclk_vals mtl_cdclk_table[] = {1417 { .refclk = 38400, .cdclk = 172800, .ratio = 16, .waveform = 0xad5a },1418 { .refclk = 38400, .cdclk = 192000, .ratio = 16, .waveform = 0xb6b6 },1419 { .refclk = 38400, .cdclk = 307200, .ratio = 16, .waveform = 0x0000 },1420 { .refclk = 38400, .cdclk = 480000, .ratio = 25, .waveform = 0x0000 },1421 { .refclk = 38400, .cdclk = 556800, .ratio = 29, .waveform = 0x0000 },1422 { .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0x0000 },1423 {}1424};1425 1426static const struct intel_cdclk_vals xe2lpd_cdclk_table[] = {1427 { .refclk = 38400, .cdclk = 153600, .ratio = 16, .waveform = 0xaaaa },1428 { .refclk = 38400, .cdclk = 172800, .ratio = 16, .waveform = 0xad5a },1429 { .refclk = 38400, .cdclk = 192000, .ratio = 16, .waveform = 0xb6b6 },1430 { .refclk = 38400, .cdclk = 211200, .ratio = 16, .waveform = 0xdbb6 },1431 { .refclk = 38400, .cdclk = 230400, .ratio = 16, .waveform = 0xeeee },1432 { .refclk = 38400, .cdclk = 249600, .ratio = 16, .waveform = 0xf7de },1433 { .refclk = 38400, .cdclk = 268800, .ratio = 16, .waveform = 0xfefe },1434 { .refclk = 38400, .cdclk = 288000, .ratio = 16, .waveform = 0xfffe },1435 { .refclk = 38400, .cdclk = 307200, .ratio = 16, .waveform = 0xffff },1436 { .refclk = 38400, .cdclk = 330000, .ratio = 25, .waveform = 0xdbb6 },1437 { .refclk = 38400, .cdclk = 360000, .ratio = 25, .waveform = 0xeeee },1438 { .refclk = 38400, .cdclk = 390000, .ratio = 25, .waveform = 0xf7de },1439 { .refclk = 38400, .cdclk = 420000, .ratio = 25, .waveform = 0xfefe },1440 { .refclk = 38400, .cdclk = 450000, .ratio = 25, .waveform = 0xfffe },1441 { .refclk = 38400, .cdclk = 480000, .ratio = 25, .waveform = 0xffff },1442 { .refclk = 38400, .cdclk = 487200, .ratio = 29, .waveform = 0xfefe },1443 { .refclk = 38400, .cdclk = 522000, .ratio = 29, .waveform = 0xfffe },1444 { .refclk = 38400, .cdclk = 556800, .ratio = 29, .waveform = 0xffff },1445 { .refclk = 38400, .cdclk = 571200, .ratio = 34, .waveform = 0xfefe },1446 { .refclk = 38400, .cdclk = 612000, .ratio = 34, .waveform = 0xfffe },1447 { .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },1448 {}1449};1450 1451/*1452 * Xe2_HPD always uses the minimal cdclk table from Wa_150154137711453 */1454static const struct intel_cdclk_vals xe2hpd_cdclk_table[] = {1455 { .refclk = 38400, .cdclk = 652800, .ratio = 34, .waveform = 0xffff },1456 {}1457};1458 1459static const int cdclk_squash_len = 16;1460 1461static int cdclk_squash_divider(u16 waveform)1462{1463 return hweight16(waveform ?: 0xffff);1464}1465 1466static int cdclk_divider(int cdclk, int vco, u16 waveform)1467{1468 /* 2 * cd2x divider */1469 return DIV_ROUND_CLOSEST(vco * cdclk_squash_divider(waveform),1470 cdclk * cdclk_squash_len);1471}1472 1473static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)1474{1475 const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;1476 int i;1477 1478 for (i = 0; table[i].refclk; i++)1479 if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&1480 table[i].cdclk >= min_cdclk)1481 return table[i].cdclk;1482 1483 drm_WARN(&dev_priv->drm, 1,1484 "Cannot satisfy minimum cdclk %d with refclk %u\n",1485 min_cdclk, dev_priv->display.cdclk.hw.ref);1486 return 0;1487}1488 1489static int bxt_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)1490{1491 const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;1492 int i;1493 1494 if (cdclk == dev_priv->display.cdclk.hw.bypass)1495 return 0;1496 1497 for (i = 0; table[i].refclk; i++)1498 if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&1499 table[i].cdclk == cdclk)1500 return dev_priv->display.cdclk.hw.ref * table[i].ratio;1501 1502 drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",1503 cdclk, dev_priv->display.cdclk.hw.ref);1504 return 0;1505}1506 1507static u8 bxt_calc_voltage_level(int cdclk)1508{1509 return DIV_ROUND_UP(cdclk, 25000);1510}1511 1512static u8 calc_voltage_level(int cdclk, int num_voltage_levels,1513 const int voltage_level_max_cdclk[])1514{1515 int voltage_level;1516 1517 for (voltage_level = 0; voltage_level < num_voltage_levels; voltage_level++) {1518 if (cdclk <= voltage_level_max_cdclk[voltage_level])1519 return voltage_level;1520 }1521 1522 MISSING_CASE(cdclk);1523 return num_voltage_levels - 1;1524}1525 1526static u8 icl_calc_voltage_level(int cdclk)1527{1528 static const int icl_voltage_level_max_cdclk[] = {1529 [0] = 312000,1530 [1] = 556800,1531 [2] = 652800,1532 };1533 1534 return calc_voltage_level(cdclk,1535 ARRAY_SIZE(icl_voltage_level_max_cdclk),1536 icl_voltage_level_max_cdclk);1537}1538 1539static u8 ehl_calc_voltage_level(int cdclk)1540{1541 static const int ehl_voltage_level_max_cdclk[] = {1542 [0] = 180000,1543 [1] = 312000,1544 [2] = 326400,1545 /*1546 * Bspec lists the limit as 556.8 MHz, but some JSL1547 * development boards (at least) boot with 652.8 MHz1548 */1549 [3] = 652800,1550 };1551 1552 return calc_voltage_level(cdclk,1553 ARRAY_SIZE(ehl_voltage_level_max_cdclk),1554 ehl_voltage_level_max_cdclk);1555}1556 1557static u8 tgl_calc_voltage_level(int cdclk)1558{1559 static const int tgl_voltage_level_max_cdclk[] = {1560 [0] = 312000,1561 [1] = 326400,1562 [2] = 556800,1563 [3] = 652800,1564 };1565 1566 return calc_voltage_level(cdclk,1567 ARRAY_SIZE(tgl_voltage_level_max_cdclk),1568 tgl_voltage_level_max_cdclk);1569}1570 1571static u8 rplu_calc_voltage_level(int cdclk)1572{1573 static const int rplu_voltage_level_max_cdclk[] = {1574 [0] = 312000,1575 [1] = 480000,1576 [2] = 556800,1577 [3] = 652800,1578 };1579 1580 return calc_voltage_level(cdclk,1581 ARRAY_SIZE(rplu_voltage_level_max_cdclk),1582 rplu_voltage_level_max_cdclk);1583}1584 1585static void icl_readout_refclk(struct drm_i915_private *dev_priv,1586 struct intel_cdclk_config *cdclk_config)1587{1588 u32 dssm = intel_de_read(dev_priv, SKL_DSSM) & ICL_DSSM_CDCLK_PLL_REFCLK_MASK;1589 1590 switch (dssm) {1591 default:1592 MISSING_CASE(dssm);1593 fallthrough;1594 case ICL_DSSM_CDCLK_PLL_REFCLK_24MHz:1595 cdclk_config->ref = 24000;1596 break;1597 case ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz:1598 cdclk_config->ref = 19200;1599 break;1600 case ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz:1601 cdclk_config->ref = 38400;1602 break;1603 }1604}1605 1606static void bxt_de_pll_readout(struct drm_i915_private *dev_priv,1607 struct intel_cdclk_config *cdclk_config)1608{1609 u32 val, ratio;1610 1611 if (IS_DG2(dev_priv))1612 cdclk_config->ref = 38400;1613 else if (DISPLAY_VER(dev_priv) >= 11)1614 icl_readout_refclk(dev_priv, cdclk_config);1615 else1616 cdclk_config->ref = 19200;1617 1618 val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE);1619 if ((val & BXT_DE_PLL_PLL_ENABLE) == 0 ||1620 (val & BXT_DE_PLL_LOCK) == 0) {1621 /*1622 * CDCLK PLL is disabled, the VCO/ratio doesn't matter, but1623 * setting it to zero is a way to signal that.1624 */1625 cdclk_config->vco = 0;1626 return;1627 }1628 1629 /*1630 * DISPLAY_VER >= 11 have the ratio directly in the PLL enable register,1631 * gen9lp had it in a separate PLL control register.1632 */1633 if (DISPLAY_VER(dev_priv) >= 11)1634 ratio = val & ICL_CDCLK_PLL_RATIO_MASK;1635 else1636 ratio = intel_de_read(dev_priv, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK;1637 1638 cdclk_config->vco = ratio * cdclk_config->ref;1639}1640 1641static void bxt_get_cdclk(struct drm_i915_private *dev_priv,1642 struct intel_cdclk_config *cdclk_config)1643{1644 u32 squash_ctl = 0;1645 u32 divider;1646 int div;1647 1648 bxt_de_pll_readout(dev_priv, cdclk_config);1649 1650 if (DISPLAY_VER(dev_priv) >= 12)1651 cdclk_config->bypass = cdclk_config->ref / 2;1652 else if (DISPLAY_VER(dev_priv) >= 11)1653 cdclk_config->bypass = 50000;1654 else1655 cdclk_config->bypass = cdclk_config->ref;1656 1657 if (cdclk_config->vco == 0) {1658 cdclk_config->cdclk = cdclk_config->bypass;1659 goto out;1660 }1661 1662 divider = intel_de_read(dev_priv, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;1663 1664 switch (divider) {1665 case BXT_CDCLK_CD2X_DIV_SEL_1:1666 div = 2;1667 break;1668 case BXT_CDCLK_CD2X_DIV_SEL_1_5:1669 div = 3;1670 break;1671 case BXT_CDCLK_CD2X_DIV_SEL_2:1672 div = 4;1673 break;1674 case BXT_CDCLK_CD2X_DIV_SEL_4:1675 div = 8;1676 break;1677 default:1678 MISSING_CASE(divider);1679 return;1680 }1681 1682 if (HAS_CDCLK_SQUASH(dev_priv))1683 squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL);1684 1685 if (squash_ctl & CDCLK_SQUASH_ENABLE) {1686 u16 waveform;1687 int size;1688 1689 size = REG_FIELD_GET(CDCLK_SQUASH_WINDOW_SIZE_MASK, squash_ctl) + 1;1690 waveform = REG_FIELD_GET(CDCLK_SQUASH_WAVEFORM_MASK, squash_ctl) >> (16 - size);1691 1692 cdclk_config->cdclk = DIV_ROUND_CLOSEST(hweight16(waveform) *1693 cdclk_config->vco, size * div);1694 } else {1695 cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_config->vco, div);1696 }1697 1698 out:1699 if (DISPLAY_VER(dev_priv) >= 20)1700 cdclk_config->joined_mbus = intel_de_read(dev_priv, MBUS_CTL) & MBUS_JOIN;1701 /*1702 * Can't read this out :( Let's assume it's1703 * at least what the CDCLK frequency requires.1704 */1705 cdclk_config->voltage_level =1706 intel_cdclk_calc_voltage_level(dev_priv, cdclk_config->cdclk);1707}1708 1709static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)1710{1711 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, 0);1712 1713 /* Timeout 200us */1714 if (intel_de_wait_for_clear(dev_priv,1715 BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))1716 drm_err(&dev_priv->drm, "timeout waiting for DE PLL unlock\n");1717 1718 dev_priv->display.cdclk.hw.vco = 0;1719}1720 1721static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)1722{1723 int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);1724 1725 intel_de_rmw(dev_priv, BXT_DE_PLL_CTL,1726 BXT_DE_PLL_RATIO_MASK, BXT_DE_PLL_RATIO(ratio));1727 1728 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);1729 1730 /* Timeout 200us */1731 if (intel_de_wait_for_set(dev_priv,1732 BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))1733 drm_err(&dev_priv->drm, "timeout waiting for DE PLL lock\n");1734 1735 dev_priv->display.cdclk.hw.vco = vco;1736}1737 1738static void icl_cdclk_pll_disable(struct drm_i915_private *dev_priv)1739{1740 intel_de_rmw(dev_priv, BXT_DE_PLL_ENABLE,1741 BXT_DE_PLL_PLL_ENABLE, 0);1742 1743 /* Timeout 200us */1744 if (intel_de_wait_for_clear(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))1745 drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL unlock\n");1746 1747 dev_priv->display.cdclk.hw.vco = 0;1748}1749 1750static void icl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)1751{1752 int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);1753 u32 val;1754 1755 val = ICL_CDCLK_PLL_RATIO(ratio);1756 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);1757 1758 val |= BXT_DE_PLL_PLL_ENABLE;1759 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);1760 1761 /* Timeout 200us */1762 if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))1763 drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL lock\n");1764 1765 dev_priv->display.cdclk.hw.vco = vco;1766}1767 1768static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)1769{1770 int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->display.cdclk.hw.ref);1771 u32 val;1772 1773 /* Write PLL ratio without disabling */1774 val = ICL_CDCLK_PLL_RATIO(ratio) | BXT_DE_PLL_PLL_ENABLE;1775 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);1776 1777 /* Submit freq change request */1778 val |= BXT_DE_PLL_FREQ_REQ;1779 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);1780 1781 /* Timeout 200us */1782 if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE,1783 BXT_DE_PLL_LOCK | BXT_DE_PLL_FREQ_REQ_ACK, 1))1784 drm_err(&dev_priv->drm, "timeout waiting for FREQ change request ack\n");1785 1786 val &= ~BXT_DE_PLL_FREQ_REQ;1787 intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);1788 1789 dev_priv->display.cdclk.hw.vco = vco;1790}1791 1792static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)1793{1794 if (DISPLAY_VER(dev_priv) >= 12) {1795 if (pipe == INVALID_PIPE)1796 return TGL_CDCLK_CD2X_PIPE_NONE;1797 else1798 return TGL_CDCLK_CD2X_PIPE(pipe);1799 } else if (DISPLAY_VER(dev_priv) >= 11) {1800 if (pipe == INVALID_PIPE)1801 return ICL_CDCLK_CD2X_PIPE_NONE;1802 else1803 return ICL_CDCLK_CD2X_PIPE(pipe);1804 } else {1805 if (pipe == INVALID_PIPE)1806 return BXT_CDCLK_CD2X_PIPE_NONE;1807 else1808 return BXT_CDCLK_CD2X_PIPE(pipe);1809 }1810}1811 1812static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,1813 int cdclk, int vco, u16 waveform)1814{1815 /* cdclk = vco / 2 / div{1,1.5,2,4} */1816 switch (cdclk_divider(cdclk, vco, waveform)) {1817 default:1818 drm_WARN_ON(&dev_priv->drm,1819 cdclk != dev_priv->display.cdclk.hw.bypass);1820 drm_WARN_ON(&dev_priv->drm, vco != 0);1821 fallthrough;1822 case 2:1823 return BXT_CDCLK_CD2X_DIV_SEL_1;1824 case 3:1825 return BXT_CDCLK_CD2X_DIV_SEL_1_5;1826 case 4:1827 return BXT_CDCLK_CD2X_DIV_SEL_2;1828 case 8:1829 return BXT_CDCLK_CD2X_DIV_SEL_4;1830 }1831}1832 1833static u16 cdclk_squash_waveform(struct drm_i915_private *dev_priv,1834 int cdclk)1835{1836 const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;1837 int i;1838 1839 if (cdclk == dev_priv->display.cdclk.hw.bypass)1840 return 0;1841 1842 for (i = 0; table[i].refclk; i++)1843 if (table[i].refclk == dev_priv->display.cdclk.hw.ref &&1844 table[i].cdclk == cdclk)1845 return table[i].waveform;1846 1847 drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",1848 cdclk, dev_priv->display.cdclk.hw.ref);1849 1850 return 0xffff;1851}1852 1853static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco)1854{1855 if (i915->display.cdclk.hw.vco != 0 &&1856 i915->display.cdclk.hw.vco != vco)1857 icl_cdclk_pll_disable(i915);1858 1859 if (i915->display.cdclk.hw.vco != vco)1860 icl_cdclk_pll_enable(i915, vco);1861}1862 1863static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco)1864{1865 if (i915->display.cdclk.hw.vco != 0 &&1866 i915->display.cdclk.hw.vco != vco)1867 bxt_de_pll_disable(i915);1868 1869 if (i915->display.cdclk.hw.vco != vco)1870 bxt_de_pll_enable(i915, vco);1871}1872 1873static void dg2_cdclk_squash_program(struct drm_i915_private *i915,1874 u16 waveform)1875{1876 u32 squash_ctl = 0;1877 1878 if (waveform)1879 squash_ctl = CDCLK_SQUASH_ENABLE |1880 CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;1881 1882 intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl);1883}1884 1885static bool cdclk_pll_is_unknown(unsigned int vco)1886{1887 /*1888 * Ensure driver does not take the crawl path for the1889 * case when the vco is set to ~0 in the1890 * sanitize path.1891 */1892 return vco == ~0;1893}1894 1895static bool mdclk_source_is_cdclk_pll(struct drm_i915_private *i915)1896{1897 return DISPLAY_VER(i915) >= 20;1898}1899 1900static u32 xe2lpd_mdclk_source_sel(struct drm_i915_private *i915)1901{1902 if (mdclk_source_is_cdclk_pll(i915))1903 return MDCLK_SOURCE_SEL_CDCLK_PLL;1904 1905 return MDCLK_SOURCE_SEL_CD2XCLK;1906}1907 1908int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,1909 const struct intel_cdclk_config *cdclk_config)1910{1911 if (mdclk_source_is_cdclk_pll(i915))1912 return DIV_ROUND_UP(cdclk_config->vco, cdclk_config->cdclk);1913 1914 /* Otherwise, source for MDCLK is CD2XCLK. */1915 return 2;1916}1917 1918static void xe2lpd_mdclk_cdclk_ratio_program(struct drm_i915_private *i915,1919 const struct intel_cdclk_config *cdclk_config)1920{1921 intel_dbuf_mdclk_cdclk_ratio_update(i915,1922 intel_mdclk_cdclk_ratio(i915, cdclk_config),1923 cdclk_config->joined_mbus);1924}1925 1926static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915,1927 const struct intel_cdclk_config *old_cdclk_config,1928 const struct intel_cdclk_config *new_cdclk_config,1929 struct intel_cdclk_config *mid_cdclk_config)1930{1931 u16 old_waveform, new_waveform, mid_waveform;1932 int old_div, new_div, mid_div;1933 1934 /* Return if PLL is in an unknown state, force a complete disable and re-enable. */1935 if (cdclk_pll_is_unknown(old_cdclk_config->vco))1936 return false;1937 1938 /* Return if both Squash and Crawl are not present */1939 if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915))1940 return false;1941 1942 old_waveform = cdclk_squash_waveform(i915, old_cdclk_config->cdclk);1943 new_waveform = cdclk_squash_waveform(i915, new_cdclk_config->cdclk);1944 1945 /* Return if Squash only or Crawl only is the desired action */1946 if (old_cdclk_config->vco == 0 || new_cdclk_config->vco == 0 ||1947 old_cdclk_config->vco == new_cdclk_config->vco ||1948 old_waveform == new_waveform)1949 return false;1950 1951 old_div = cdclk_divider(old_cdclk_config->cdclk,1952 old_cdclk_config->vco, old_waveform);1953 new_div = cdclk_divider(new_cdclk_config->cdclk,1954 new_cdclk_config->vco, new_waveform);1955 1956 /*1957 * Should not happen currently. We might need more midpoint1958 * transitions if we need to also change the cd2x divider.1959 */1960 if (drm_WARN_ON(&i915->drm, old_div != new_div))1961 return false;1962 1963 *mid_cdclk_config = *new_cdclk_config;1964 1965 /*1966 * Populate the mid_cdclk_config accordingly.1967 * - If moving to a higher cdclk, the desired action is squashing.1968 * The mid cdclk config should have the new (squash) waveform.1969 * - If moving to a lower cdclk, the desired action is crawling.1970 * The mid cdclk config should have the new vco.1971 */1972 1973 if (cdclk_squash_divider(new_waveform) > cdclk_squash_divider(old_waveform)) {1974 mid_cdclk_config->vco = old_cdclk_config->vco;1975 mid_div = old_div;1976 mid_waveform = new_waveform;1977 } else {1978 mid_cdclk_config->vco = new_cdclk_config->vco;1979 mid_div = new_div;1980 mid_waveform = old_waveform;1981 }1982 1983 mid_cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_squash_divider(mid_waveform) *1984 mid_cdclk_config->vco,1985 cdclk_squash_len * mid_div);1986 1987 /* make sure the mid clock came out sane */1988 1989 drm_WARN_ON(&i915->drm, mid_cdclk_config->cdclk <1990 min(old_cdclk_config->cdclk, new_cdclk_config->cdclk));1991 drm_WARN_ON(&i915->drm, mid_cdclk_config->cdclk >1992 i915->display.cdclk.max_cdclk_freq);1993 drm_WARN_ON(&i915->drm, cdclk_squash_waveform(i915, mid_cdclk_config->cdclk) !=1994 mid_waveform);1995 1996 return true;1997}1998 1999static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv)2000{2001 return (DISPLAY_VER_FULL(dev_priv) == IP_VER(20, 0) ||2002 DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 0) ||2003 IS_DG2(dev_priv)) &&2004 dev_priv->display.cdclk.hw.vco > 0;2005}2006 2007static u32 bxt_cdclk_ctl(struct drm_i915_private *i915,2008 const struct intel_cdclk_config *cdclk_config,2009 enum pipe pipe)2010{2011 int cdclk = cdclk_config->cdclk;2012 int vco = cdclk_config->vco;2013 u16 waveform;2014 u32 val;2015 2016 waveform = cdclk_squash_waveform(i915, cdclk);2017 2018 val = bxt_cdclk_cd2x_div_sel(i915, cdclk, vco, waveform) |2019 bxt_cdclk_cd2x_pipe(i915, pipe);2020 2021 /*2022 * Disable SSA Precharge when CD clock frequency < 500 MHz,2023 * enable otherwise.2024 */2025 if ((IS_GEMINILAKE(i915) || IS_BROXTON(i915)) &&2026 cdclk >= 500000)2027 val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;2028 2029 if (DISPLAY_VER(i915) >= 20)2030 val |= xe2lpd_mdclk_source_sel(i915);2031 else2032 val |= skl_cdclk_decimal(cdclk);2033 2034 return val;2035}2036 2037static void _bxt_set_cdclk(struct drm_i915_private *dev_priv,2038 const struct intel_cdclk_config *cdclk_config,2039 enum pipe pipe)2040{2041 int cdclk = cdclk_config->cdclk;2042 int vco = cdclk_config->vco;2043 2044 if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0 &&2045 !cdclk_pll_is_unknown(dev_priv->display.cdclk.hw.vco)) {2046 if (dev_priv->display.cdclk.hw.vco != vco)2047 adlp_cdclk_pll_crawl(dev_priv, vco);2048 } else if (DISPLAY_VER(dev_priv) >= 11) {2049 /* wa_15010685871: dg2, mtl */2050 if (pll_enable_wa_needed(dev_priv))2051 dg2_cdclk_squash_program(dev_priv, 0);2052 2053 icl_cdclk_pll_update(dev_priv, vco);2054 } else2055 bxt_cdclk_pll_update(dev_priv, vco);2056 2057 if (HAS_CDCLK_SQUASH(dev_priv)) {2058 u16 waveform = cdclk_squash_waveform(dev_priv, cdclk);2059 2060 dg2_cdclk_squash_program(dev_priv, waveform);2061 }2062 2063 intel_de_write(dev_priv, CDCLK_CTL, bxt_cdclk_ctl(dev_priv, cdclk_config, pipe));2064 2065 if (pipe != INVALID_PIPE)2066 intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(dev_priv, pipe));2067}2068 2069static void bxt_set_cdclk(struct drm_i915_private *dev_priv,2070 const struct intel_cdclk_config *cdclk_config,2071 enum pipe pipe)2072{2073 struct intel_cdclk_config mid_cdclk_config;2074 int cdclk = cdclk_config->cdclk;2075 int ret = 0;2076 2077 /*2078 * Inform power controller of upcoming frequency change.2079 * Display versions 14 and beyond do not follow the PUnit2080 * mailbox communication, skip2081 * this step.2082 */2083 if (DISPLAY_VER(dev_priv) >= 14 || IS_DG2(dev_priv))2084 /* NOOP */;2085 else if (DISPLAY_VER(dev_priv) >= 11)2086 ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,2087 SKL_CDCLK_PREPARE_FOR_CHANGE,2088 SKL_CDCLK_READY_FOR_CHANGE,2089 SKL_CDCLK_READY_FOR_CHANGE, 3);2090 else2091 /*2092 * BSpec requires us to wait up to 150usec, but that leads to2093 * timeouts; the 2ms used here is based on experiment.2094 */2095 ret = snb_pcode_write_timeout(&dev_priv->uncore,2096 HSW_PCODE_DE_WRITE_FREQ_REQ,2097 0x80000000, 150, 2);2098 2099 if (ret) {2100 drm_err(&dev_priv->drm,2101 "Failed to inform PCU about cdclk change (err %d, freq %d)\n",2102 ret, cdclk);2103 return;2104 }2105 2106 if (DISPLAY_VER(dev_priv) >= 20 && cdclk < dev_priv->display.cdclk.hw.cdclk)2107 xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config);2108 2109 if (cdclk_compute_crawl_and_squash_midpoint(dev_priv, &dev_priv->display.cdclk.hw,2110 cdclk_config, &mid_cdclk_config)) {2111 _bxt_set_cdclk(dev_priv, &mid_cdclk_config, pipe);2112 _bxt_set_cdclk(dev_priv, cdclk_config, pipe);2113 } else {2114 _bxt_set_cdclk(dev_priv, cdclk_config, pipe);2115 }2116 2117 if (DISPLAY_VER(dev_priv) >= 20 && cdclk > dev_priv->display.cdclk.hw.cdclk)2118 xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config);2119 2120 if (DISPLAY_VER(dev_priv) >= 14)2121 /*2122 * NOOP - No Pcode communication needed for2123 * Display versions 14 and beyond2124 */;2125 else if (DISPLAY_VER(dev_priv) >= 11 && !IS_DG2(dev_priv))2126 ret = snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,2127 cdclk_config->voltage_level);2128 if (DISPLAY_VER(dev_priv) < 11) {2129 /*2130 * The timeout isn't specified, the 2ms used here is based on2131 * experiment.2132 * FIXME: Waiting for the request completion could be delayed2133 * until the next PCODE request based on BSpec.2134 */2135 ret = snb_pcode_write_timeout(&dev_priv->uncore,2136 HSW_PCODE_DE_WRITE_FREQ_REQ,2137 cdclk_config->voltage_level,2138 150, 2);2139 }2140 if (ret) {2141 drm_err(&dev_priv->drm,2142 "PCode CDCLK freq set failed, (err %d, freq %d)\n",2143 ret, cdclk);2144 return;2145 }2146 2147 intel_update_cdclk(dev_priv);2148 2149 if (DISPLAY_VER(dev_priv) >= 11)2150 /*2151 * Can't read out the voltage level :(2152 * Let's just assume everything is as expected.2153 */2154 dev_priv->display.cdclk.hw.voltage_level = cdclk_config->voltage_level;2155}2156 2157static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)2158{2159 u32 cdctl, expected;2160 int cdclk, vco;2161 2162 intel_update_cdclk(dev_priv);2163 intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "Current CDCLK");2164 2165 if (dev_priv->display.cdclk.hw.vco == 0 ||2166 dev_priv->display.cdclk.hw.cdclk == dev_priv->display.cdclk.hw.bypass)2167 goto sanitize;2168 2169 /* Make sure this is a legal cdclk value for the platform */2170 cdclk = bxt_calc_cdclk(dev_priv, dev_priv->display.cdclk.hw.cdclk);2171 if (cdclk != dev_priv->display.cdclk.hw.cdclk)2172 goto sanitize;2173 2174 /* Make sure the VCO is correct for the cdclk */2175 vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);2176 if (vco != dev_priv->display.cdclk.hw.vco)2177 goto sanitize;2178 2179 /*2180 * Some BIOS versions leave an incorrect decimal frequency value and2181 * set reserved MBZ bits in CDCLK_CTL at least during exiting from S4,2182 * so sanitize this register.2183 */2184 cdctl = intel_de_read(dev_priv, CDCLK_CTL);2185 expected = bxt_cdclk_ctl(dev_priv, &dev_priv->display.cdclk.hw, INVALID_PIPE);2186 2187 /*2188 * Let's ignore the pipe field, since BIOS could have configured the2189 * dividers both synching to an active pipe, or asynchronously2190 * (PIPE_NONE).2191 */2192 cdctl &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE);2193 expected &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE);2194 2195 if (cdctl == expected)2196 /* All well; nothing to sanitize */2197 return;2198 2199sanitize:2200 drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");2201 2202 /* force cdclk programming */2203 dev_priv->display.cdclk.hw.cdclk = 0;2204 2205 /* force full PLL disable + enable */2206 dev_priv->display.cdclk.hw.vco = ~0;2207}2208 2209static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv)2210{2211 struct intel_cdclk_config cdclk_config;2212 2213 bxt_sanitize_cdclk(dev_priv);2214 2215 if (dev_priv->display.cdclk.hw.cdclk != 0 &&2216 dev_priv->display.cdclk.hw.vco != 0)2217 return;2218 2219 cdclk_config = dev_priv->display.cdclk.hw;2220 2221 /*2222 * FIXME:2223 * - The initial CDCLK needs to be read from VBT.2224 * Need to make this change after VBT has changes for BXT.2225 */2226 cdclk_config.cdclk = bxt_calc_cdclk(dev_priv, 0);2227 cdclk_config.vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk_config.cdclk);2228 cdclk_config.voltage_level =2229 intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk);2230 2231 bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);2232}2233 2234static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv)2235{2236 struct intel_cdclk_config cdclk_config = dev_priv->display.cdclk.hw;2237 2238 cdclk_config.cdclk = cdclk_config.bypass;2239 cdclk_config.vco = 0;2240 cdclk_config.voltage_level =2241 intel_cdclk_calc_voltage_level(dev_priv, cdclk_config.cdclk);2242 2243 bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);2244}2245 2246/**2247 * intel_cdclk_init_hw - Initialize CDCLK hardware2248 * @i915: i915 device2249 *2250 * Initialize CDCLK. This consists mainly of initializing dev_priv->display.cdclk.hw and2251 * sanitizing the state of the hardware if needed. This is generally done only2252 * during the display core initialization sequence, after which the DMC will2253 * take care of turning CDCLK off/on as needed.2254 */2255void intel_cdclk_init_hw(struct drm_i915_private *i915)2256{2257 if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915))2258 bxt_cdclk_init_hw(i915);2259 else if (DISPLAY_VER(i915) == 9)2260 skl_cdclk_init_hw(i915);2261}2262 2263/**2264 * intel_cdclk_uninit_hw - Uninitialize CDCLK hardware2265 * @i915: i915 device2266 *2267 * Uninitialize CDCLK. This is done only during the display core2268 * uninitialization sequence.2269 */2270void intel_cdclk_uninit_hw(struct drm_i915_private *i915)2271{2272 if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915))2273 bxt_cdclk_uninit_hw(i915);2274 else if (DISPLAY_VER(i915) == 9)2275 skl_cdclk_uninit_hw(i915);2276}2277 2278static bool intel_cdclk_can_crawl_and_squash(struct drm_i915_private *i915,2279 const struct intel_cdclk_config *a,2280 const struct intel_cdclk_config *b)2281{2282 u16 old_waveform;2283 u16 new_waveform;2284 2285 drm_WARN_ON(&i915->drm, cdclk_pll_is_unknown(a->vco));2286 2287 if (a->vco == 0 || b->vco == 0)2288 return false;2289 2290 if (!HAS_CDCLK_CRAWL(i915) || !HAS_CDCLK_SQUASH(i915))2291 return false;2292 2293 old_waveform = cdclk_squash_waveform(i915, a->cdclk);2294 new_waveform = cdclk_squash_waveform(i915, b->cdclk);2295 2296 return a->vco != b->vco &&2297 old_waveform != new_waveform;2298}2299 2300static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv,2301 const struct intel_cdclk_config *a,2302 const struct intel_cdclk_config *b)2303{2304 int a_div, b_div;2305 2306 if (!HAS_CDCLK_CRAWL(dev_priv))2307 return false;2308 2309 /*2310 * The vco and cd2x divider will change independently2311 * from each, so we disallow cd2x change when crawling.2312 */2313 a_div = DIV_ROUND_CLOSEST(a->vco, a->cdclk);2314 b_div = DIV_ROUND_CLOSEST(b->vco, b->cdclk);2315 2316 return a->vco != 0 && b->vco != 0 &&2317 a->vco != b->vco &&2318 a_div == b_div &&2319 a->ref == b->ref;2320}2321 2322static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv,2323 const struct intel_cdclk_config *a,2324 const struct intel_cdclk_config *b)2325{2326 /*2327 * FIXME should store a bit more state in intel_cdclk_config2328 * to differentiate squasher vs. cd2x divider properly. For2329 * the moment all platforms with squasher use a fixed cd2x2330 * divider.2331 */2332 if (!HAS_CDCLK_SQUASH(dev_priv))2333 return false;2334 2335 return a->cdclk != b->cdclk &&2336 a->vco != 0 &&2337 a->vco == b->vco &&2338 a->ref == b->ref;2339}2340 2341/**2342 * intel_cdclk_clock_changed - Check whether the clock changed2343 * @a: first CDCLK configuration2344 * @b: second CDCLK configuration2345 *2346 * Returns:2347 * True if CDCLK changed in a way that requires re-programming and2348 * False otherwise.2349 */2350bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,2351 const struct intel_cdclk_config *b)2352{2353 return a->cdclk != b->cdclk ||2354 a->vco != b->vco ||2355 a->ref != b->ref;2356}2357 2358/**2359 * intel_cdclk_can_cd2x_update - Determine if changing between the two CDCLK2360 * configurations requires only a cd2x divider update2361 * @dev_priv: i915 device2362 * @a: first CDCLK configuration2363 * @b: second CDCLK configuration2364 *2365 * Returns:2366 * True if changing between the two CDCLK configurations2367 * can be done with just a cd2x divider update, false if not.2368 */2369static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,2370 const struct intel_cdclk_config *a,2371 const struct intel_cdclk_config *b)2372{2373 /* Older hw doesn't have the capability */2374 if (DISPLAY_VER(dev_priv) < 10 && !IS_BROXTON(dev_priv))2375 return false;2376 2377 /*2378 * FIXME should store a bit more state in intel_cdclk_config2379 * to differentiate squasher vs. cd2x divider properly. For2380 * the moment all platforms with squasher use a fixed cd2x2381 * divider.2382 */2383 if (HAS_CDCLK_SQUASH(dev_priv))2384 return false;2385 2386 return a->cdclk != b->cdclk &&2387 a->vco != 0 &&2388 a->vco == b->vco &&2389 a->ref == b->ref;2390}2391 2392/**2393 * intel_cdclk_changed - Determine if two CDCLK configurations are different2394 * @a: first CDCLK configuration2395 * @b: second CDCLK configuration2396 *2397 * Returns:2398 * True if the CDCLK configurations don't match, false if they do.2399 */2400static bool intel_cdclk_changed(const struct intel_cdclk_config *a,2401 const struct intel_cdclk_config *b)2402{2403 return intel_cdclk_clock_changed(a, b) ||2404 a->voltage_level != b->voltage_level;2405}2406 2407void intel_cdclk_dump_config(struct drm_i915_private *i915,2408 const struct intel_cdclk_config *cdclk_config,2409 const char *context)2410{2411 drm_dbg_kms(&i915->drm, "%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n",2412 context, cdclk_config->cdclk, cdclk_config->vco,2413 cdclk_config->ref, cdclk_config->bypass,2414 cdclk_config->voltage_level);2415}2416 2417static void intel_pcode_notify(struct drm_i915_private *i915,2418 u8 voltage_level,2419 u8 active_pipe_count,2420 u16 cdclk,2421 bool cdclk_update_valid,2422 bool pipe_count_update_valid)2423{2424 int ret;2425 u32 update_mask = 0;2426 2427 if (!IS_DG2(i915))2428 return;2429 2430 update_mask = DISPLAY_TO_PCODE_UPDATE_MASK(cdclk, active_pipe_count, voltage_level);2431 2432 if (cdclk_update_valid)2433 update_mask |= DISPLAY_TO_PCODE_CDCLK_VALID;2434 2435 if (pipe_count_update_valid)2436 update_mask |= DISPLAY_TO_PCODE_PIPE_COUNT_VALID;2437 2438 ret = skl_pcode_request(&i915->uncore, SKL_PCODE_CDCLK_CONTROL,2439 SKL_CDCLK_PREPARE_FOR_CHANGE |2440 update_mask,2441 SKL_CDCLK_READY_FOR_CHANGE,2442 SKL_CDCLK_READY_FOR_CHANGE, 3);2443 if (ret)2444 drm_err(&i915->drm,2445 "Failed to inform PCU about display config (err %d)\n",2446 ret);2447}2448 2449static void intel_set_cdclk(struct drm_i915_private *dev_priv,2450 const struct intel_cdclk_config *cdclk_config,2451 enum pipe pipe, const char *context)2452{2453 struct intel_encoder *encoder;2454 2455 if (!intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config))2456 return;2457 2458 if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->display.funcs.cdclk->set_cdclk))2459 return;2460 2461 intel_cdclk_dump_config(dev_priv, cdclk_config, context);2462 2463 for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {2464 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);2465 2466 intel_psr_pause(intel_dp);2467 }2468 2469 intel_audio_cdclk_change_pre(dev_priv);2470 2471 /*2472 * Lock aux/gmbus while we change cdclk in case those2473 * functions use cdclk. Not all platforms/ports do,2474 * but we'll lock them all for simplicity.2475 */2476 mutex_lock(&dev_priv->display.gmbus.mutex);2477 for_each_intel_dp(&dev_priv->drm, encoder) {2478 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);2479 2480 mutex_lock_nest_lock(&intel_dp->aux.hw_mutex,2481 &dev_priv->display.gmbus.mutex);2482 }2483 2484 intel_cdclk_set_cdclk(dev_priv, cdclk_config, pipe);2485 2486 for_each_intel_dp(&dev_priv->drm, encoder) {2487 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);2488 2489 mutex_unlock(&intel_dp->aux.hw_mutex);2490 }2491 mutex_unlock(&dev_priv->display.gmbus.mutex);2492 2493 for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {2494 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);2495 2496 intel_psr_resume(intel_dp);2497 }2498 2499 intel_audio_cdclk_change_post(dev_priv);2500 2501 if (drm_WARN(&dev_priv->drm,2502 intel_cdclk_changed(&dev_priv->display.cdclk.hw, cdclk_config),2503 "cdclk state doesn't match!\n")) {2504 intel_cdclk_dump_config(dev_priv, &dev_priv->display.cdclk.hw, "[hw state]");2505 intel_cdclk_dump_config(dev_priv, cdclk_config, "[sw state]");2506 }2507}2508 2509static void intel_cdclk_pcode_pre_notify(struct intel_atomic_state *state)2510{2511 struct drm_i915_private *i915 = to_i915(state->base.dev);2512 const struct intel_cdclk_state *old_cdclk_state =2513 intel_atomic_get_old_cdclk_state(state);2514 const struct intel_cdclk_state *new_cdclk_state =2515 intel_atomic_get_new_cdclk_state(state);2516 unsigned int cdclk = 0; u8 voltage_level, num_active_pipes = 0;2517 bool change_cdclk, update_pipe_count;2518 2519 if (!intel_cdclk_changed(&old_cdclk_state->actual,2520 &new_cdclk_state->actual) &&2521 new_cdclk_state->active_pipes ==2522 old_cdclk_state->active_pipes)2523 return;2524 2525 /* According to "Sequence Before Frequency Change", voltage level set to 0x3 */2526 voltage_level = DISPLAY_TO_PCODE_VOLTAGE_MAX;2527 2528 change_cdclk = new_cdclk_state->actual.cdclk != old_cdclk_state->actual.cdclk;2529 update_pipe_count = hweight8(new_cdclk_state->active_pipes) >2530 hweight8(old_cdclk_state->active_pipes);2531 2532 /*2533 * According to "Sequence Before Frequency Change",2534 * if CDCLK is increasing, set bits 25:16 to upcoming CDCLK,2535 * if CDCLK is decreasing or not changing, set bits 25:16 to current CDCLK,2536 * which basically means we choose the maximum of old and new CDCLK, if we know both2537 */2538 if (change_cdclk)2539 cdclk = max(new_cdclk_state->actual.cdclk, old_cdclk_state->actual.cdclk);2540 2541 /*2542 * According to "Sequence For Pipe Count Change",2543 * if pipe count is increasing, set bits 25:16 to upcoming pipe count2544 * (power well is enabled)2545 * no action if it is decreasing, before the change2546 */2547 if (update_pipe_count)2548 num_active_pipes = hweight8(new_cdclk_state->active_pipes);2549 2550 intel_pcode_notify(i915, voltage_level, num_active_pipes, cdclk,2551 change_cdclk, update_pipe_count);2552}2553 2554static void intel_cdclk_pcode_post_notify(struct intel_atomic_state *state)2555{2556 struct drm_i915_private *i915 = to_i915(state->base.dev);2557 const struct intel_cdclk_state *new_cdclk_state =2558 intel_atomic_get_new_cdclk_state(state);2559 const struct intel_cdclk_state *old_cdclk_state =2560 intel_atomic_get_old_cdclk_state(state);2561 unsigned int cdclk = 0; u8 voltage_level, num_active_pipes = 0;2562 bool update_cdclk, update_pipe_count;2563 2564 /* According to "Sequence After Frequency Change", set voltage to used level */2565 voltage_level = new_cdclk_state->actual.voltage_level;2566 2567 update_cdclk = new_cdclk_state->actual.cdclk != old_cdclk_state->actual.cdclk;2568 update_pipe_count = hweight8(new_cdclk_state->active_pipes) <2569 hweight8(old_cdclk_state->active_pipes);2570 2571 /*2572 * According to "Sequence After Frequency Change",2573 * set bits 25:16 to current CDCLK2574 */2575 if (update_cdclk)2576 cdclk = new_cdclk_state->actual.cdclk;2577 2578 /*2579 * According to "Sequence For Pipe Count Change",2580 * if pipe count is decreasing, set bits 25:16 to current pipe count,2581 * after the change(power well is disabled)2582 * no action if it is increasing, after the change2583 */2584 if (update_pipe_count)2585 num_active_pipes = hweight8(new_cdclk_state->active_pipes);2586 2587 intel_pcode_notify(i915, voltage_level, num_active_pipes, cdclk,2588 update_cdclk, update_pipe_count);2589}2590 2591bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state)2592{2593 const struct intel_cdclk_state *old_cdclk_state =2594 intel_atomic_get_old_cdclk_state(state);2595 const struct intel_cdclk_state *new_cdclk_state =2596 intel_atomic_get_new_cdclk_state(state);2597 2598 return new_cdclk_state && !new_cdclk_state->disable_pipes &&2599 new_cdclk_state->actual.cdclk < old_cdclk_state->actual.cdclk;2600}2601 2602/**2603 * intel_set_cdclk_pre_plane_update - Push the CDCLK state to the hardware2604 * @state: intel atomic state2605 *2606 * Program the hardware before updating the HW plane state based on the2607 * new CDCLK state, if necessary.2608 */2609void2610intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)2611{2612 struct drm_i915_private *i915 = to_i915(state->base.dev);2613 const struct intel_cdclk_state *old_cdclk_state =2614 intel_atomic_get_old_cdclk_state(state);2615 const struct intel_cdclk_state *new_cdclk_state =2616 intel_atomic_get_new_cdclk_state(state);2617 struct intel_cdclk_config cdclk_config;2618 enum pipe pipe;2619 2620 if (!intel_cdclk_changed(&old_cdclk_state->actual,2621 &new_cdclk_state->actual))2622 return;2623 2624 if (IS_DG2(i915))2625 intel_cdclk_pcode_pre_notify(state);2626 2627 if (new_cdclk_state->disable_pipes) {2628 cdclk_config = new_cdclk_state->actual;2629 pipe = INVALID_PIPE;2630 } else {2631 if (new_cdclk_state->actual.cdclk >= old_cdclk_state->actual.cdclk) {2632 cdclk_config = new_cdclk_state->actual;2633 pipe = new_cdclk_state->pipe;2634 } else {2635 cdclk_config = old_cdclk_state->actual;2636 pipe = INVALID_PIPE;2637 }2638 2639 cdclk_config.voltage_level = max(new_cdclk_state->actual.voltage_level,2640 old_cdclk_state->actual.voltage_level);2641 }2642 2643 /*2644 * mbus joining will be changed later by2645 * intel_dbuf_mbus_{pre,post}_ddb_update()2646 */2647 cdclk_config.joined_mbus = old_cdclk_state->actual.joined_mbus;2648 2649 drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);2650 2651 intel_set_cdclk(i915, &cdclk_config, pipe,2652 "Pre changing CDCLK to");2653}2654 2655/**2656 * intel_set_cdclk_post_plane_update - Push the CDCLK state to the hardware2657 * @state: intel atomic state2658 *2659 * Program the hardware after updating the HW plane state based on the2660 * new CDCLK state, if necessary.2661 */2662void2663intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)2664{2665 struct drm_i915_private *i915 = to_i915(state->base.dev);2666 const struct intel_cdclk_state *old_cdclk_state =2667 intel_atomic_get_old_cdclk_state(state);2668 const struct intel_cdclk_state *new_cdclk_state =2669 intel_atomic_get_new_cdclk_state(state);2670 enum pipe pipe;2671 2672 if (!intel_cdclk_changed(&old_cdclk_state->actual,2673 &new_cdclk_state->actual))2674 return;2675 2676 if (IS_DG2(i915))2677 intel_cdclk_pcode_post_notify(state);2678 2679 if (!new_cdclk_state->disable_pipes &&2680 new_cdclk_state->actual.cdclk < old_cdclk_state->actual.cdclk)2681 pipe = new_cdclk_state->pipe;2682 else2683 pipe = INVALID_PIPE;2684 2685 drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);2686 2687 intel_set_cdclk(i915, &new_cdclk_state->actual, pipe,2688 "Post changing CDCLK to");2689}2690 2691static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)2692{2693 struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);2694 int pixel_rate = crtc_state->pixel_rate;2695 2696 if (DISPLAY_VER(dev_priv) >= 10)2697 return DIV_ROUND_UP(pixel_rate, 2);2698 else if (DISPLAY_VER(dev_priv) == 9 ||2699 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))2700 return pixel_rate;2701 else if (IS_CHERRYVIEW(dev_priv))2702 return DIV_ROUND_UP(pixel_rate * 100, 95);2703 else if (crtc_state->double_wide)2704 return DIV_ROUND_UP(pixel_rate * 100, 90 * 2);2705 else2706 return DIV_ROUND_UP(pixel_rate * 100, 90);2707}2708 2709static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)2710{2711 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);2712 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);2713 struct intel_plane *plane;2714 int min_cdclk = 0;2715 2716 for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane)2717 min_cdclk = max(crtc_state->min_cdclk[plane->id], min_cdclk);2718 2719 return min_cdclk;2720}2721 2722static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)2723{2724 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);2725 struct drm_i915_private *i915 = to_i915(crtc->base.dev);2726 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);2727 int min_cdclk = 0;2728 2729 /*2730 * When we decide to use only one VDSC engine, since2731 * each VDSC operates with 1 ppc throughput, pixel clock2732 * cannot be higher than the VDSC clock (cdclk)2733 * If there 2 VDSC engines, then pixel clock can't be higher than2734 * VDSC clock(cdclk) * 2 and so on.2735 */2736 min_cdclk = max_t(int, min_cdclk,2737 DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances));2738 2739 if (crtc_state->joiner_pipes) {2740 int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock);2741 2742 /*2743 * According to Bigjoiner bw check:2744 * compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / Pixel clock2745 *2746 * We have already computed compressed_bpp, so now compute the min CDCLK that2747 * is required to support this compressed_bpp.2748 *2749 * => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner Interface bits)2750 *2751 * Since PPC = 2 with bigjoiner2752 * => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits2753 */2754 int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24;2755 int min_cdclk_bj =2756 (fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) *2757 pixel_clock) / (2 * bigjoiner_interface_bits);2758 2759 min_cdclk = max(min_cdclk, min_cdclk_bj);2760 }2761 2762 return min_cdclk;2763}2764 2765int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)2766{2767 struct drm_i915_private *dev_priv =2768 to_i915(crtc_state->uapi.crtc->dev);2769 int min_cdclk;2770 2771 if (!crtc_state->hw.enable)2772 return 0;2773 2774 min_cdclk = intel_pixel_rate_to_cdclk(crtc_state);2775 2776 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */2777 if (IS_BROADWELL(dev_priv) && hsw_crtc_state_ips_capable(crtc_state))2778 min_cdclk = DIV_ROUND_UP(min_cdclk * 100, 95);2779 2780 /* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz,2781 * audio enabled, port width x4, and link rate HBR2 (5.4 GHz), or else2782 * there may be audio corruption or screen corruption." This cdclk2783 * restriction for GLK is 316.8 MHz.2784 */2785 if (intel_crtc_has_dp_encoder(crtc_state) &&2786 crtc_state->has_audio &&2787 crtc_state->port_clock >= 540000 &&2788 crtc_state->lane_count == 4) {2789 if (DISPLAY_VER(dev_priv) == 10) {2790 /* Display WA #1145: glk */2791 min_cdclk = max(316800, min_cdclk);2792 } else if (DISPLAY_VER(dev_priv) == 9 || IS_BROADWELL(dev_priv)) {2793 /* Display WA #1144: skl,bxt */2794 min_cdclk = max(432000, min_cdclk);2795 }2796 }2797 2798 /*2799 * According to BSpec, "The CD clock frequency must be at least twice2800 * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.2801 */2802 if (crtc_state->has_audio && DISPLAY_VER(dev_priv) >= 9)2803 min_cdclk = max(2 * 96000, min_cdclk);2804 2805 /*2806 * "For DP audio configuration, cdclk frequency shall be set to2807 * meet the following requirements:2808 * DP Link Frequency(MHz) | Cdclk frequency(MHz)2809 * 270 | 320 or higher2810 * 162 | 200 or higher"2811 */2812 if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&2813 intel_crtc_has_dp_encoder(crtc_state) && crtc_state->has_audio)2814 min_cdclk = max(crtc_state->port_clock, min_cdclk);2815 2816 /*2817 * On Valleyview some DSI panels lose (v|h)sync when the clock is lower2818 * than 320000KHz.2819 */2820 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&2821 IS_VALLEYVIEW(dev_priv))2822 min_cdclk = max(320000, min_cdclk);2823 2824 /*2825 * On Geminilake once the CDCLK gets as low as 792002826 * picture gets unstable, despite that values are2827 * correct for DSI PLL and DE PLL.2828 */2829 if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&2830 IS_GEMINILAKE(dev_priv))2831 min_cdclk = max(158400, min_cdclk);2832 2833 /* Account for additional needs from the planes */2834 min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);2835 2836 if (crtc_state->dsc.compression_enable)2837 min_cdclk = max(min_cdclk, intel_vdsc_min_cdclk(crtc_state));2838 2839 return min_cdclk;2840}2841 2842static int intel_compute_min_cdclk(struct intel_atomic_state *state)2843{2844 struct drm_i915_private *dev_priv = to_i915(state->base.dev);2845 struct intel_cdclk_state *cdclk_state =2846 intel_atomic_get_new_cdclk_state(state);2847 const struct intel_bw_state *bw_state;2848 struct intel_crtc *crtc;2849 struct intel_crtc_state *crtc_state;2850 int min_cdclk, i;2851 enum pipe pipe;2852 2853 for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {2854 int ret;2855 2856 min_cdclk = intel_crtc_compute_min_cdclk(crtc_state);2857 if (min_cdclk < 0)2858 return min_cdclk;2859 2860 if (cdclk_state->min_cdclk[crtc->pipe] == min_cdclk)2861 continue;2862 2863 cdclk_state->min_cdclk[crtc->pipe] = min_cdclk;2864 2865 ret = intel_atomic_lock_global_state(&cdclk_state->base);2866 if (ret)2867 return ret;2868 }2869 2870 bw_state = intel_atomic_get_new_bw_state(state);2871 if (bw_state) {2872 min_cdclk = intel_bw_min_cdclk(dev_priv, bw_state);2873 2874 if (cdclk_state->bw_min_cdclk != min_cdclk) {2875 int ret;2876 2877 cdclk_state->bw_min_cdclk = min_cdclk;2878 2879 ret = intel_atomic_lock_global_state(&cdclk_state->base);2880 if (ret)2881 return ret;2882 }2883 }2884 2885 min_cdclk = max(cdclk_state->force_min_cdclk,2886 cdclk_state->bw_min_cdclk);2887 for_each_pipe(dev_priv, pipe)2888 min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);2889 2890 /*2891 * Avoid glk_force_audio_cdclk() causing excessive screen2892 * blinking when multiple pipes are active by making sure2893 * CDCLK frequency is always high enough for audio. With a2894 * single active pipe we can always change CDCLK frequency2895 * by changing the cd2x divider (see glk_cdclk_table[]) and2896 * thus a full modeset won't be needed then.2897 */2898 if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes &&2899 !is_power_of_2(cdclk_state->active_pipes))2900 min_cdclk = max(2 * 96000, min_cdclk);2901 2902 if (min_cdclk > dev_priv->display.cdclk.max_cdclk_freq) {2903 drm_dbg_kms(&dev_priv->drm,2904 "required cdclk (%d kHz) exceeds max (%d kHz)\n",2905 min_cdclk, dev_priv->display.cdclk.max_cdclk_freq);2906 return -EINVAL;2907 }2908 2909 return min_cdclk;2910}2911 2912/*2913 * Account for port clock min voltage level requirements.2914 * This only really does something on DISPLA_VER >= 11 but can be2915 * called on earlier platforms as well.2916 *2917 * Note that this functions assumes that 0 is2918 * the lowest voltage value, and higher values2919 * correspond to increasingly higher voltages.2920 *2921 * Should that relationship no longer hold on2922 * future platforms this code will need to be2923 * adjusted.2924 */2925static int bxt_compute_min_voltage_level(struct intel_atomic_state *state)2926{2927 struct drm_i915_private *dev_priv = to_i915(state->base.dev);2928 struct intel_cdclk_state *cdclk_state =2929 intel_atomic_get_new_cdclk_state(state);2930 struct intel_crtc *crtc;2931 struct intel_crtc_state *crtc_state;2932 u8 min_voltage_level;2933 int i;2934 enum pipe pipe;2935 2936 for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {2937 int ret;2938 2939 if (crtc_state->hw.enable)2940 min_voltage_level = crtc_state->min_voltage_level;2941 else2942 min_voltage_level = 0;2943 2944 if (cdclk_state->min_voltage_level[crtc->pipe] == min_voltage_level)2945 continue;2946 2947 cdclk_state->min_voltage_level[crtc->pipe] = min_voltage_level;2948 2949 ret = intel_atomic_lock_global_state(&cdclk_state->base);2950 if (ret)2951 return ret;2952 }2953 2954 min_voltage_level = 0;2955 for_each_pipe(dev_priv, pipe)2956 min_voltage_level = max(cdclk_state->min_voltage_level[pipe],2957 min_voltage_level);2958 2959 return min_voltage_level;2960}2961 2962static int vlv_modeset_calc_cdclk(struct intel_atomic_state *state)2963{2964 struct drm_i915_private *dev_priv = to_i915(state->base.dev);2965 struct intel_cdclk_state *cdclk_state =2966 intel_atomic_get_new_cdclk_state(state);2967 int min_cdclk, cdclk;2968 2969 min_cdclk = intel_compute_min_cdclk(state);2970 if (min_cdclk < 0)2971 return min_cdclk;2972 2973 cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);2974 2975 cdclk_state->logical.cdclk = cdclk;2976 cdclk_state->logical.voltage_level =2977 vlv_calc_voltage_level(dev_priv, cdclk);2978 2979 if (!cdclk_state->active_pipes) {2980 cdclk = vlv_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk);2981 2982 cdclk_state->actual.cdclk = cdclk;2983 cdclk_state->actual.voltage_level =2984 vlv_calc_voltage_level(dev_priv, cdclk);2985 } else {2986 cdclk_state->actual = cdclk_state->logical;2987 }2988 2989 return 0;2990}2991 2992static int bdw_modeset_calc_cdclk(struct intel_atomic_state *state)2993{2994 struct intel_cdclk_state *cdclk_state =2995 intel_atomic_get_new_cdclk_state(state);2996 int min_cdclk, cdclk;2997 2998 min_cdclk = intel_compute_min_cdclk(state);2999 if (min_cdclk < 0)3000 return min_cdclk;3001 3002 cdclk = bdw_calc_cdclk(min_cdclk);3003 3004 cdclk_state->logical.cdclk = cdclk;3005 cdclk_state->logical.voltage_level =3006 bdw_calc_voltage_level(cdclk);3007 3008 if (!cdclk_state->active_pipes) {3009 cdclk = bdw_calc_cdclk(cdclk_state->force_min_cdclk);3010 3011 cdclk_state->actual.cdclk = cdclk;3012 cdclk_state->actual.voltage_level =3013 bdw_calc_voltage_level(cdclk);3014 } else {3015 cdclk_state->actual = cdclk_state->logical;3016 }3017 3018 return 0;3019}3020 3021static int skl_dpll0_vco(struct intel_atomic_state *state)3022{3023 struct drm_i915_private *dev_priv = to_i915(state->base.dev);3024 struct intel_cdclk_state *cdclk_state =3025 intel_atomic_get_new_cdclk_state(state);3026 struct intel_crtc *crtc;3027 struct intel_crtc_state *crtc_state;3028 int vco, i;3029 3030 vco = cdclk_state->logical.vco;3031 if (!vco)3032 vco = dev_priv->display.cdclk.skl_preferred_vco_freq;3033 3034 for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {3035 if (!crtc_state->hw.enable)3036 continue;3037 3038 if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))3039 continue;3040 3041 /*3042 * DPLL0 VCO may need to be adjusted to get the correct3043 * clock for eDP. This will affect cdclk as well.3044 */3045 switch (crtc_state->port_clock / 2) {3046 case 108000:3047 case 216000:3048 vco = 8640000;3049 break;3050 default:3051 vco = 8100000;3052 break;3053 }3054 }3055 3056 return vco;3057}3058 3059static int skl_modeset_calc_cdclk(struct intel_atomic_state *state)3060{3061 struct intel_cdclk_state *cdclk_state =3062 intel_atomic_get_new_cdclk_state(state);3063 int min_cdclk, cdclk, vco;3064 3065 min_cdclk = intel_compute_min_cdclk(state);3066 if (min_cdclk < 0)3067 return min_cdclk;3068 3069 vco = skl_dpll0_vco(state);3070 3071 cdclk = skl_calc_cdclk(min_cdclk, vco);3072 3073 cdclk_state->logical.vco = vco;3074 cdclk_state->logical.cdclk = cdclk;3075 cdclk_state->logical.voltage_level =3076 skl_calc_voltage_level(cdclk);3077 3078 if (!cdclk_state->active_pipes) {3079 cdclk = skl_calc_cdclk(cdclk_state->force_min_cdclk, vco);3080 3081 cdclk_state->actual.vco = vco;3082 cdclk_state->actual.cdclk = cdclk;3083 cdclk_state->actual.voltage_level =3084 skl_calc_voltage_level(cdclk);3085 } else {3086 cdclk_state->actual = cdclk_state->logical;3087 }3088 3089 return 0;3090}3091 3092static int bxt_modeset_calc_cdclk(struct intel_atomic_state *state)3093{3094 struct drm_i915_private *dev_priv = to_i915(state->base.dev);3095 struct intel_cdclk_state *cdclk_state =3096 intel_atomic_get_new_cdclk_state(state);3097 int min_cdclk, min_voltage_level, cdclk, vco;3098 3099 min_cdclk = intel_compute_min_cdclk(state);3100 if (min_cdclk < 0)3101 return min_cdclk;3102 3103 min_voltage_level = bxt_compute_min_voltage_level(state);3104 if (min_voltage_level < 0)3105 return min_voltage_level;3106 3107 cdclk = bxt_calc_cdclk(dev_priv, min_cdclk);3108 vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);3109 3110 cdclk_state->logical.vco = vco;3111 cdclk_state->logical.cdclk = cdclk;3112 cdclk_state->logical.voltage_level =3113 max_t(int, min_voltage_level,3114 intel_cdclk_calc_voltage_level(dev_priv, cdclk));3115 3116 if (!cdclk_state->active_pipes) {3117 cdclk = bxt_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk);3118 vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);3119 3120 cdclk_state->actual.vco = vco;3121 cdclk_state->actual.cdclk = cdclk;3122 cdclk_state->actual.voltage_level =3123 intel_cdclk_calc_voltage_level(dev_priv, cdclk);3124 } else {3125 cdclk_state->actual = cdclk_state->logical;3126 }3127 3128 return 0;3129}3130 3131static int fixed_modeset_calc_cdclk(struct intel_atomic_state *state)3132{3133 int min_cdclk;3134 3135 /*3136 * We can't change the cdclk frequency, but we still want to3137 * check that the required minimum frequency doesn't exceed3138 * the actual cdclk frequency.3139 */3140 min_cdclk = intel_compute_min_cdclk(state);3141 if (min_cdclk < 0)3142 return min_cdclk;3143 3144 return 0;3145}3146 3147static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_global_obj *obj)3148{3149 struct intel_cdclk_state *cdclk_state;3150 3151 cdclk_state = kmemdup(obj->state, sizeof(*cdclk_state), GFP_KERNEL);3152 if (!cdclk_state)3153 return NULL;3154 3155 cdclk_state->pipe = INVALID_PIPE;3156 cdclk_state->disable_pipes = false;3157 3158 return &cdclk_state->base;3159}3160 3161static void intel_cdclk_destroy_state(struct intel_global_obj *obj,3162 struct intel_global_state *state)3163{3164 kfree(state);3165}3166 3167static const struct intel_global_state_funcs intel_cdclk_funcs = {3168 .atomic_duplicate_state = intel_cdclk_duplicate_state,3169 .atomic_destroy_state = intel_cdclk_destroy_state,3170};3171 3172struct intel_cdclk_state *3173intel_atomic_get_cdclk_state(struct intel_atomic_state *state)3174{3175 struct drm_i915_private *dev_priv = to_i915(state->base.dev);3176 struct intel_global_state *cdclk_state;3177 3178 cdclk_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.cdclk.obj);3179 if (IS_ERR(cdclk_state))3180 return ERR_CAST(cdclk_state);3181 3182 return to_intel_cdclk_state(cdclk_state);3183}3184 3185int intel_cdclk_atomic_check(struct intel_atomic_state *state,3186 bool *need_cdclk_calc)3187{3188 const struct intel_cdclk_state *old_cdclk_state;3189 const struct intel_cdclk_state *new_cdclk_state;3190 struct intel_plane_state __maybe_unused *plane_state;3191 struct intel_plane *plane;3192 int ret;3193 int i;3194 3195 /*3196 * active_planes bitmask has been updated, and potentially affected3197 * planes are part of the state. We can now compute the minimum cdclk3198 * for each plane.3199 */3200 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {3201 ret = intel_plane_calc_min_cdclk(state, plane, need_cdclk_calc);3202 if (ret)3203 return ret;3204 }3205 3206 ret = intel_bw_calc_min_cdclk(state, need_cdclk_calc);3207 if (ret)3208 return ret;3209 3210 old_cdclk_state = intel_atomic_get_old_cdclk_state(state);3211 new_cdclk_state = intel_atomic_get_new_cdclk_state(state);3212 3213 if (new_cdclk_state &&3214 old_cdclk_state->force_min_cdclk != new_cdclk_state->force_min_cdclk)3215 *need_cdclk_calc = true;3216 3217 return 0;3218}3219 3220int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joined_mbus)3221{3222 struct intel_cdclk_state *cdclk_state;3223 3224 cdclk_state = intel_atomic_get_cdclk_state(state);3225 if (IS_ERR(cdclk_state))3226 return PTR_ERR(cdclk_state);3227 3228 cdclk_state->actual.joined_mbus = joined_mbus;3229 cdclk_state->logical.joined_mbus = joined_mbus;3230 3231 return intel_atomic_lock_global_state(&cdclk_state->base);3232}3233 3234int intel_cdclk_init(struct drm_i915_private *dev_priv)3235{3236 struct intel_cdclk_state *cdclk_state;3237 3238 cdclk_state = kzalloc(sizeof(*cdclk_state), GFP_KERNEL);3239 if (!cdclk_state)3240 return -ENOMEM;3241 3242 intel_atomic_global_obj_init(dev_priv, &dev_priv->display.cdclk.obj,3243 &cdclk_state->base, &intel_cdclk_funcs);3244 3245 return 0;3246}3247 3248static bool intel_cdclk_need_serialize(struct drm_i915_private *i915,3249 const struct intel_cdclk_state *old_cdclk_state,3250 const struct intel_cdclk_state *new_cdclk_state)3251{3252 bool power_well_cnt_changed = hweight8(old_cdclk_state->active_pipes) !=3253 hweight8(new_cdclk_state->active_pipes);3254 bool cdclk_changed = intel_cdclk_changed(&old_cdclk_state->actual,3255 &new_cdclk_state->actual);3256 /*3257 * We need to poke hw for gen >= 12, because we notify PCode if3258 * pipe power well count changes.3259 */3260 return cdclk_changed || (IS_DG2(i915) && power_well_cnt_changed);3261}3262 3263int intel_modeset_calc_cdclk(struct intel_atomic_state *state)3264{3265 struct drm_i915_private *dev_priv = to_i915(state->base.dev);3266 const struct intel_cdclk_state *old_cdclk_state;3267 struct intel_cdclk_state *new_cdclk_state;3268 enum pipe pipe = INVALID_PIPE;3269 int ret;3270 3271 new_cdclk_state = intel_atomic_get_cdclk_state(state);3272 if (IS_ERR(new_cdclk_state))3273 return PTR_ERR(new_cdclk_state);3274 3275 old_cdclk_state = intel_atomic_get_old_cdclk_state(state);3276 3277 new_cdclk_state->active_pipes =3278 intel_calc_active_pipes(state, old_cdclk_state->active_pipes);3279 3280 ret = intel_cdclk_modeset_calc_cdclk(state);3281 if (ret)3282 return ret;3283 3284 if (intel_cdclk_need_serialize(dev_priv, old_cdclk_state, new_cdclk_state)) {3285 /*3286 * Also serialize commits across all crtcs3287 * if the actual hw needs to be poked.3288 */3289 ret = intel_atomic_serialize_global_state(&new_cdclk_state->base);3290 if (ret)3291 return ret;3292 } else if (old_cdclk_state->active_pipes != new_cdclk_state->active_pipes ||3293 old_cdclk_state->force_min_cdclk != new_cdclk_state->force_min_cdclk ||3294 intel_cdclk_changed(&old_cdclk_state->logical,3295 &new_cdclk_state->logical)) {3296 ret = intel_atomic_lock_global_state(&new_cdclk_state->base);3297 if (ret)3298 return ret;3299 } else {3300 return 0;3301 }3302 3303 if (is_power_of_2(new_cdclk_state->active_pipes) &&3304 intel_cdclk_can_cd2x_update(dev_priv,3305 &old_cdclk_state->actual,3306 &new_cdclk_state->actual)) {3307 struct intel_crtc *crtc;3308 struct intel_crtc_state *crtc_state;3309 3310 pipe = ilog2(new_cdclk_state->active_pipes);3311 crtc = intel_crtc_for_pipe(dev_priv, pipe);3312 3313 crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);3314 if (IS_ERR(crtc_state))3315 return PTR_ERR(crtc_state);3316 3317 if (intel_crtc_needs_modeset(crtc_state))3318 pipe = INVALID_PIPE;3319 }3320 3321 if (intel_cdclk_can_crawl_and_squash(dev_priv,3322 &old_cdclk_state->actual,3323 &new_cdclk_state->actual)) {3324 drm_dbg_kms(&dev_priv->drm,3325 "Can change cdclk via crawling and squashing\n");3326 } else if (intel_cdclk_can_squash(dev_priv,3327 &old_cdclk_state->actual,3328 &new_cdclk_state->actual)) {3329 drm_dbg_kms(&dev_priv->drm,3330 "Can change cdclk via squashing\n");3331 } else if (intel_cdclk_can_crawl(dev_priv,3332 &old_cdclk_state->actual,3333 &new_cdclk_state->actual)) {3334 drm_dbg_kms(&dev_priv->drm,3335 "Can change cdclk via crawling\n");3336 } else if (pipe != INVALID_PIPE) {3337 new_cdclk_state->pipe = pipe;3338 3339 drm_dbg_kms(&dev_priv->drm,3340 "Can change cdclk cd2x divider with pipe %c active\n",3341 pipe_name(pipe));3342 } else if (intel_cdclk_clock_changed(&old_cdclk_state->actual,3343 &new_cdclk_state->actual)) {3344 /* All pipes must be switched off while we change the cdclk. */3345 ret = intel_modeset_all_pipes_late(state, "CDCLK change");3346 if (ret)3347 return ret;3348 3349 new_cdclk_state->disable_pipes = true;3350 3351 drm_dbg_kms(&dev_priv->drm,3352 "Modeset required for cdclk change\n");3353 }3354 3355 if (intel_mdclk_cdclk_ratio(dev_priv, &old_cdclk_state->actual) !=3356 intel_mdclk_cdclk_ratio(dev_priv, &new_cdclk_state->actual)) {3357 int ratio = intel_mdclk_cdclk_ratio(dev_priv, &new_cdclk_state->actual);3358 3359 ret = intel_dbuf_state_set_mdclk_cdclk_ratio(state, ratio);3360 if (ret)3361 return ret;3362 }3363 3364 drm_dbg_kms(&dev_priv->drm,3365 "New cdclk calculated to be logical %u kHz, actual %u kHz\n",3366 new_cdclk_state->logical.cdclk,3367 new_cdclk_state->actual.cdclk);3368 drm_dbg_kms(&dev_priv->drm,3369 "New voltage level calculated to be logical %u, actual %u\n",3370 new_cdclk_state->logical.voltage_level,3371 new_cdclk_state->actual.voltage_level);3372 3373 return 0;3374}3375 3376static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)3377{3378 int max_cdclk_freq = dev_priv->display.cdclk.max_cdclk_freq;3379 3380 if (DISPLAY_VER(dev_priv) >= 10)3381 return 2 * max_cdclk_freq;3382 else if (DISPLAY_VER(dev_priv) == 9 ||3383 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))3384 return max_cdclk_freq;3385 else if (IS_CHERRYVIEW(dev_priv))3386 return max_cdclk_freq*95/100;3387 else if (DISPLAY_VER(dev_priv) < 4)3388 return 2*max_cdclk_freq*90/100;3389 else3390 return max_cdclk_freq*90/100;3391}3392 3393/**3394 * intel_update_max_cdclk - Determine the maximum support CDCLK frequency3395 * @dev_priv: i915 device3396 *3397 * Determine the maximum CDCLK frequency the platform supports, and also3398 * derive the maximum dot clock frequency the maximum CDCLK frequency3399 * allows.3400 */3401void intel_update_max_cdclk(struct drm_i915_private *dev_priv)3402{3403 if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {3404 if (dev_priv->display.cdclk.hw.ref == 24000)3405 dev_priv->display.cdclk.max_cdclk_freq = 552000;3406 else3407 dev_priv->display.cdclk.max_cdclk_freq = 556800;3408 } else if (DISPLAY_VER(dev_priv) >= 11) {3409 if (dev_priv->display.cdclk.hw.ref == 24000)3410 dev_priv->display.cdclk.max_cdclk_freq = 648000;3411 else3412 dev_priv->display.cdclk.max_cdclk_freq = 652800;3413 } else if (IS_GEMINILAKE(dev_priv)) {3414 dev_priv->display.cdclk.max_cdclk_freq = 316800;3415 } else if (IS_BROXTON(dev_priv)) {3416 dev_priv->display.cdclk.max_cdclk_freq = 624000;3417 } else if (DISPLAY_VER(dev_priv) == 9) {3418 u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;3419 int max_cdclk, vco;3420 3421 vco = dev_priv->display.cdclk.skl_preferred_vco_freq;3422 drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);3423 3424 /*3425 * Use the lower (vco 8640) cdclk values as a3426 * first guess. skl_calc_cdclk() will correct it3427 * if the preferred vco is 8100 instead.3428 */3429 if (limit == SKL_DFSM_CDCLK_LIMIT_675)3430 max_cdclk = 617143;3431 else if (limit == SKL_DFSM_CDCLK_LIMIT_540)3432 max_cdclk = 540000;3433 else if (limit == SKL_DFSM_CDCLK_LIMIT_450)3434 max_cdclk = 432000;3435 else3436 max_cdclk = 308571;3437 3438 dev_priv->display.cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);3439 } else if (IS_BROADWELL(dev_priv)) {3440 /*3441 * FIXME with extra cooling we can allow3442 * 540 MHz for ULX and 675 Mhz for ULT.3443 * How can we know if extra cooling is3444 * available? PCI ID, VTB, something else?3445 */3446 if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)3447 dev_priv->display.cdclk.max_cdclk_freq = 450000;3448 else if (IS_BROADWELL_ULX(dev_priv))3449 dev_priv->display.cdclk.max_cdclk_freq = 450000;3450 else if (IS_BROADWELL_ULT(dev_priv))3451 dev_priv->display.cdclk.max_cdclk_freq = 540000;3452 else3453 dev_priv->display.cdclk.max_cdclk_freq = 675000;3454 } else if (IS_CHERRYVIEW(dev_priv)) {3455 dev_priv->display.cdclk.max_cdclk_freq = 320000;3456 } else if (IS_VALLEYVIEW(dev_priv)) {3457 dev_priv->display.cdclk.max_cdclk_freq = 400000;3458 } else {3459 /* otherwise assume cdclk is fixed */3460 dev_priv->display.cdclk.max_cdclk_freq = dev_priv->display.cdclk.hw.cdclk;3461 }3462 3463 dev_priv->display.cdclk.max_dotclk_freq = intel_compute_max_dotclk(dev_priv);3464 3465 drm_dbg(&dev_priv->drm, "Max CD clock rate: %d kHz\n",3466 dev_priv->display.cdclk.max_cdclk_freq);3467 3468 drm_dbg(&dev_priv->drm, "Max dotclock rate: %d kHz\n",3469 dev_priv->display.cdclk.max_dotclk_freq);3470}3471 3472/**3473 * intel_update_cdclk - Determine the current CDCLK frequency3474 * @dev_priv: i915 device3475 *3476 * Determine the current CDCLK frequency.3477 */3478void intel_update_cdclk(struct drm_i915_private *dev_priv)3479{3480 intel_cdclk_get_cdclk(dev_priv, &dev_priv->display.cdclk.hw);3481 3482 /*3483 * 9:0 CMBUS [sic] CDCLK frequency (cdfreq):3484 * Programmng [sic] note: bit[9:2] should be programmed to the number3485 * of cdclk that generates 4MHz reference clock freq which is used to3486 * generate GMBus clock. This will vary with the cdclk freq.3487 */3488 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))3489 intel_de_write(dev_priv, GMBUSFREQ_VLV,3490 DIV_ROUND_UP(dev_priv->display.cdclk.hw.cdclk, 1000));3491}3492 3493static int dg1_rawclk(struct drm_i915_private *dev_priv)3494{3495 /*3496 * DG1 always uses a 38.4 MHz rawclk. The bspec tells us3497 * "Program Numerator=2, Denominator=4, Divider=37 decimal."3498 */3499 intel_de_write(dev_priv, PCH_RAWCLK_FREQ,3500 CNP_RAWCLK_DEN(4) | CNP_RAWCLK_DIV(37) | ICP_RAWCLK_NUM(2));3501 3502 return 38400;3503}3504 3505static int cnp_rawclk(struct drm_i915_private *dev_priv)3506{3507 u32 rawclk;3508 int divider, fraction;3509 3510 if (intel_de_read(dev_priv, SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) {3511 /* 24 MHz */3512 divider = 24000;3513 fraction = 0;3514 } else {3515 /* 19.2 MHz */3516 divider = 19000;3517 fraction = 200;3518 }3519 3520 rawclk = CNP_RAWCLK_DIV(divider / 1000);3521 if (fraction) {3522 int numerator = 1;3523 3524 rawclk |= CNP_RAWCLK_DEN(DIV_ROUND_CLOSEST(numerator * 1000,3525 fraction) - 1);3526 if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)3527 rawclk |= ICP_RAWCLK_NUM(numerator);3528 }3529 3530 intel_de_write(dev_priv, PCH_RAWCLK_FREQ, rawclk);3531 return divider + fraction;3532}3533 3534static int pch_rawclk(struct drm_i915_private *dev_priv)3535{3536 return (intel_de_read(dev_priv, PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;3537}3538 3539static int vlv_hrawclk(struct drm_i915_private *dev_priv)3540{3541 /* RAWCLK_FREQ_VLV register updated from power well code */3542 return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",3543 CCK_DISPLAY_REF_CLOCK_CONTROL);3544}3545 3546static int i9xx_hrawclk(struct drm_i915_private *i915)3547{3548 /* hrawclock is 1/4 the FSB frequency */3549 return DIV_ROUND_CLOSEST(i9xx_fsb_freq(i915), 4);3550}3551 3552/**3553 * intel_read_rawclk - Determine the current RAWCLK frequency3554 * @dev_priv: i915 device3555 *3556 * Determine the current RAWCLK frequency. RAWCLK is a fixed3557 * frequency clock so this needs to done only once.3558 */3559u32 intel_read_rawclk(struct drm_i915_private *dev_priv)3560{3561 u32 freq;3562 3563 if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL)3564 /*3565 * MTL always uses a 38.4 MHz rawclk. The bspec tells us3566 * "RAWCLK_FREQ defaults to the values for 38.4 and does3567 * not need to be programmed."3568 */3569 freq = 38400;3570 else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)3571 freq = dg1_rawclk(dev_priv);3572 else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)3573 freq = cnp_rawclk(dev_priv);3574 else if (HAS_PCH_SPLIT(dev_priv))3575 freq = pch_rawclk(dev_priv);3576 else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))3577 freq = vlv_hrawclk(dev_priv);3578 else if (DISPLAY_VER(dev_priv) >= 3)3579 freq = i9xx_hrawclk(dev_priv);3580 else3581 /* no rawclk on other platforms, or no need to know it */3582 return 0;3583 3584 return freq;3585}3586 3587static int i915_cdclk_info_show(struct seq_file *m, void *unused)3588{3589 struct drm_i915_private *i915 = m->private;3590 3591 seq_printf(m, "Current CD clock frequency: %d kHz\n", i915->display.cdclk.hw.cdclk);3592 seq_printf(m, "Max CD clock frequency: %d kHz\n", i915->display.cdclk.max_cdclk_freq);3593 seq_printf(m, "Max pixel clock frequency: %d kHz\n", i915->display.cdclk.max_dotclk_freq);3594 3595 return 0;3596}3597 3598DEFINE_SHOW_ATTRIBUTE(i915_cdclk_info);3599 3600void intel_cdclk_debugfs_register(struct drm_i915_private *i915)3601{3602 struct drm_minor *minor = i915->drm.primary;3603 3604 debugfs_create_file("i915_cdclk_info", 0444, minor->debugfs_root,3605 i915, &i915_cdclk_info_fops);3606}3607 3608static const struct intel_cdclk_funcs rplu_cdclk_funcs = {3609 .get_cdclk = bxt_get_cdclk,3610 .set_cdclk = bxt_set_cdclk,3611 .modeset_calc_cdclk = bxt_modeset_calc_cdclk,3612 .calc_voltage_level = rplu_calc_voltage_level,3613};3614 3615static const struct intel_cdclk_funcs tgl_cdclk_funcs = {3616 .get_cdclk = bxt_get_cdclk,3617 .set_cdclk = bxt_set_cdclk,3618 .modeset_calc_cdclk = bxt_modeset_calc_cdclk,3619 .calc_voltage_level = tgl_calc_voltage_level,3620};3621 3622static const struct intel_cdclk_funcs ehl_cdclk_funcs = {3623 .get_cdclk = bxt_get_cdclk,3624 .set_cdclk = bxt_set_cdclk,3625 .modeset_calc_cdclk = bxt_modeset_calc_cdclk,3626 .calc_voltage_level = ehl_calc_voltage_level,3627};3628 3629static const struct intel_cdclk_funcs icl_cdclk_funcs = {3630 .get_cdclk = bxt_get_cdclk,3631 .set_cdclk = bxt_set_cdclk,3632 .modeset_calc_cdclk = bxt_modeset_calc_cdclk,3633 .calc_voltage_level = icl_calc_voltage_level,3634};3635 3636static const struct intel_cdclk_funcs bxt_cdclk_funcs = {3637 .get_cdclk = bxt_get_cdclk,3638 .set_cdclk = bxt_set_cdclk,3639 .modeset_calc_cdclk = bxt_modeset_calc_cdclk,3640 .calc_voltage_level = bxt_calc_voltage_level,3641};3642 3643static const struct intel_cdclk_funcs skl_cdclk_funcs = {3644 .get_cdclk = skl_get_cdclk,3645 .set_cdclk = skl_set_cdclk,3646 .modeset_calc_cdclk = skl_modeset_calc_cdclk,3647};3648 3649static const struct intel_cdclk_funcs bdw_cdclk_funcs = {3650 .get_cdclk = bdw_get_cdclk,3651 .set_cdclk = bdw_set_cdclk,3652 .modeset_calc_cdclk = bdw_modeset_calc_cdclk,3653};3654 3655static const struct intel_cdclk_funcs chv_cdclk_funcs = {3656 .get_cdclk = vlv_get_cdclk,3657 .set_cdclk = chv_set_cdclk,3658 .modeset_calc_cdclk = vlv_modeset_calc_cdclk,3659};3660 3661static const struct intel_cdclk_funcs vlv_cdclk_funcs = {3662 .get_cdclk = vlv_get_cdclk,3663 .set_cdclk = vlv_set_cdclk,3664 .modeset_calc_cdclk = vlv_modeset_calc_cdclk,3665};3666 3667static const struct intel_cdclk_funcs hsw_cdclk_funcs = {3668 .get_cdclk = hsw_get_cdclk,3669 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3670};3671 3672/* SNB, IVB, 965G, 945G */3673static const struct intel_cdclk_funcs fixed_400mhz_cdclk_funcs = {3674 .get_cdclk = fixed_400mhz_get_cdclk,3675 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3676};3677 3678static const struct intel_cdclk_funcs ilk_cdclk_funcs = {3679 .get_cdclk = fixed_450mhz_get_cdclk,3680 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3681};3682 3683static const struct intel_cdclk_funcs gm45_cdclk_funcs = {3684 .get_cdclk = gm45_get_cdclk,3685 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3686};3687 3688/* G45 uses G33 */3689 3690static const struct intel_cdclk_funcs i965gm_cdclk_funcs = {3691 .get_cdclk = i965gm_get_cdclk,3692 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3693};3694 3695/* i965G uses fixed 400 */3696 3697static const struct intel_cdclk_funcs pnv_cdclk_funcs = {3698 .get_cdclk = pnv_get_cdclk,3699 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3700};3701 3702static const struct intel_cdclk_funcs g33_cdclk_funcs = {3703 .get_cdclk = g33_get_cdclk,3704 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3705};3706 3707static const struct intel_cdclk_funcs i945gm_cdclk_funcs = {3708 .get_cdclk = i945gm_get_cdclk,3709 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3710};3711 3712/* i945G uses fixed 400 */3713 3714static const struct intel_cdclk_funcs i915gm_cdclk_funcs = {3715 .get_cdclk = i915gm_get_cdclk,3716 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3717};3718 3719static const struct intel_cdclk_funcs i915g_cdclk_funcs = {3720 .get_cdclk = fixed_333mhz_get_cdclk,3721 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3722};3723 3724static const struct intel_cdclk_funcs i865g_cdclk_funcs = {3725 .get_cdclk = fixed_266mhz_get_cdclk,3726 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3727};3728 3729static const struct intel_cdclk_funcs i85x_cdclk_funcs = {3730 .get_cdclk = i85x_get_cdclk,3731 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3732};3733 3734static const struct intel_cdclk_funcs i845g_cdclk_funcs = {3735 .get_cdclk = fixed_200mhz_get_cdclk,3736 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3737};3738 3739static const struct intel_cdclk_funcs i830_cdclk_funcs = {3740 .get_cdclk = fixed_133mhz_get_cdclk,3741 .modeset_calc_cdclk = fixed_modeset_calc_cdclk,3742};3743 3744/**3745 * intel_init_cdclk_hooks - Initialize CDCLK related modesetting hooks3746 * @dev_priv: i915 device3747 */3748void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)3749{3750 if (DISPLAY_VER(dev_priv) >= 20) {3751 dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;3752 dev_priv->display.cdclk.table = xe2lpd_cdclk_table;3753 } else if (DISPLAY_VER_FULL(dev_priv) >= IP_VER(14, 1)) {3754 dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;3755 dev_priv->display.cdclk.table = xe2hpd_cdclk_table;3756 } else if (DISPLAY_VER(dev_priv) >= 14) {3757 dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;3758 dev_priv->display.cdclk.table = mtl_cdclk_table;3759 } else if (IS_DG2(dev_priv)) {3760 dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;3761 dev_priv->display.cdclk.table = dg2_cdclk_table;3762 } else if (IS_ALDERLAKE_P(dev_priv)) {3763 /* Wa_22011320316:adl-p[a0] */3764 if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) {3765 dev_priv->display.cdclk.table = adlp_a_step_cdclk_table;3766 dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;3767 } else if (IS_RAPTORLAKE_U(dev_priv)) {3768 dev_priv->display.cdclk.table = rplu_cdclk_table;3769 dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;3770 } else {3771 dev_priv->display.cdclk.table = adlp_cdclk_table;3772 dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;3773 }3774 } else if (IS_ROCKETLAKE(dev_priv)) {3775 dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;3776 dev_priv->display.cdclk.table = rkl_cdclk_table;3777 } else if (DISPLAY_VER(dev_priv) >= 12) {3778 dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;3779 dev_priv->display.cdclk.table = icl_cdclk_table;3780 } else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {3781 dev_priv->display.funcs.cdclk = &ehl_cdclk_funcs;3782 dev_priv->display.cdclk.table = icl_cdclk_table;3783 } else if (DISPLAY_VER(dev_priv) >= 11) {3784 dev_priv->display.funcs.cdclk = &icl_cdclk_funcs;3785 dev_priv->display.cdclk.table = icl_cdclk_table;3786 } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {3787 dev_priv->display.funcs.cdclk = &bxt_cdclk_funcs;3788 if (IS_GEMINILAKE(dev_priv))3789 dev_priv->display.cdclk.table = glk_cdclk_table;3790 else3791 dev_priv->display.cdclk.table = bxt_cdclk_table;3792 } else if (DISPLAY_VER(dev_priv) == 9) {3793 dev_priv->display.funcs.cdclk = &skl_cdclk_funcs;3794 } else if (IS_BROADWELL(dev_priv)) {3795 dev_priv->display.funcs.cdclk = &bdw_cdclk_funcs;3796 } else if (IS_HASWELL(dev_priv)) {3797 dev_priv->display.funcs.cdclk = &hsw_cdclk_funcs;3798 } else if (IS_CHERRYVIEW(dev_priv)) {3799 dev_priv->display.funcs.cdclk = &chv_cdclk_funcs;3800 } else if (IS_VALLEYVIEW(dev_priv)) {3801 dev_priv->display.funcs.cdclk = &vlv_cdclk_funcs;3802 } else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) {3803 dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs;3804 } else if (IS_IRONLAKE(dev_priv)) {3805 dev_priv->display.funcs.cdclk = &ilk_cdclk_funcs;3806 } else if (IS_GM45(dev_priv)) {3807 dev_priv->display.funcs.cdclk = &gm45_cdclk_funcs;3808 } else if (IS_G45(dev_priv)) {3809 dev_priv->display.funcs.cdclk = &g33_cdclk_funcs;3810 } else if (IS_I965GM(dev_priv)) {3811 dev_priv->display.funcs.cdclk = &i965gm_cdclk_funcs;3812 } else if (IS_I965G(dev_priv)) {3813 dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs;3814 } else if (IS_PINEVIEW(dev_priv)) {3815 dev_priv->display.funcs.cdclk = &pnv_cdclk_funcs;3816 } else if (IS_G33(dev_priv)) {3817 dev_priv->display.funcs.cdclk = &g33_cdclk_funcs;3818 } else if (IS_I945GM(dev_priv)) {3819 dev_priv->display.funcs.cdclk = &i945gm_cdclk_funcs;3820 } else if (IS_I945G(dev_priv)) {3821 dev_priv->display.funcs.cdclk = &fixed_400mhz_cdclk_funcs;3822 } else if (IS_I915GM(dev_priv)) {3823 dev_priv->display.funcs.cdclk = &i915gm_cdclk_funcs;3824 } else if (IS_I915G(dev_priv)) {3825 dev_priv->display.funcs.cdclk = &i915g_cdclk_funcs;3826 } else if (IS_I865G(dev_priv)) {3827 dev_priv->display.funcs.cdclk = &i865g_cdclk_funcs;3828 } else if (IS_I85X(dev_priv)) {3829 dev_priv->display.funcs.cdclk = &i85x_cdclk_funcs;3830 } else if (IS_I845G(dev_priv)) {3831 dev_priv->display.funcs.cdclk = &i845g_cdclk_funcs;3832 } else if (IS_I830(dev_priv)) {3833 dev_priv->display.funcs.cdclk = &i830_cdclk_funcs;3834 }3835 3836 if (drm_WARN(&dev_priv->drm, !dev_priv->display.funcs.cdclk,3837 "Unknown platform. Assuming i830\n"))3838 dev_priv->display.funcs.cdclk = &i830_cdclk_funcs;3839}3840