brintos

brintos / linux-shallow public Read only

0
0
Text · 111.0 KiB · aa3ba66 Raw
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