FILE
vlv_clock.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/i915/display/vlv_clock.c
1// SPDX-License-Identifier: MIT 2/* Copyright © 2025 Intel Corporation */ 3 4#include <drm/drm_print.h> 5 6#include "intel_display_core.h" 7#include "intel_display_types.h" 8#include "vlv_clock.h" 9#include "vlv_sideband.h" 10 11/* 12 * FIXME: The caching of hpll_freq and czclk_freq relies on the first calls 13 * occurring at a time when they can actually be read. This appears to be the 14 * case, but is somewhat fragile. Make the initialization explicit at a point 15 * where they can be reliably read. 16 */ 17 18/* returns HPLL frequency in kHz */ 19int vlv_clock_get_hpll_vco(struct drm_device *drm) 20{ 21 struct intel_display *display = to_intel_display(drm); 22 int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 }; 23 24 if (!display->vlv_clock.hpll_freq) { 25 vlv_cck_get(drm); 26 /* Obtain SKU information */ 27 hpll_freq = vlv_cck_read(drm, CCK_FUSE_REG) & 28 CCK_FUSE_HPLL_FREQ_MASK; 29 vlv_cck_put(drm); 30 31 display->vlv_clock.hpll_freq = vco_freq[hpll_freq] * 1000; 32 33 drm_dbg_kms(drm, "HPLL frequency: %d kHz\n", display->vlv_clock.hpll_freq); 34 } 35 36 return display->vlv_clock.hpll_freq; 37} 38 39static int vlv_clock_get_cck(struct drm_device *drm, 40 const char *name, u32 reg, int ref_freq) 41{ 42 u32 val; 43 int divider; 44 45 vlv_cck_get(drm); 46 val = vlv_cck_read(drm, reg); 47 vlv_cck_put(drm); 48 49 divider = val & CCK_FREQUENCY_VALUES; 50 51 drm_WARN(drm, (val & CCK_FREQUENCY_STATUS) != 52 (divider << CCK_FREQUENCY_STATUS_SHIFT), 53 "%s change in progress\n", name); 54 55 return DIV_ROUND_CLOSEST(ref_freq << 1, divider + 1); 56} 57 58int vlv_clock_get_hrawclk(struct drm_device *drm) 59{ 60 /* RAWCLK_FREQ_VLV register updated from power well code */ 61 return vlv_clock_get_cck(drm, "hrawclk", CCK_DISPLAY_REF_CLOCK_CONTROL, 62 vlv_clock_get_hpll_vco(drm)); 63} 64 65int vlv_clock_get_czclk(struct drm_device *drm) 66{ 67 struct intel_display *display = to_intel_display(drm); 68 69 if (!display->vlv_clock.czclk_freq) { 70 display->vlv_clock.czclk_freq = vlv_clock_get_cck(drm, "czclk", CCK_CZ_CLOCK_CONTROL, 71 vlv_clock_get_hpll_vco(drm)); 72 drm_dbg_kms(drm, "CZ clock rate: %d kHz\n", display->vlv_clock.czclk_freq); 73 } 74 75 return display->vlv_clock.czclk_freq; 76} 77 78int vlv_clock_get_cdclk(struct drm_device *drm) 79{ 80 return vlv_clock_get_cck(drm, "cdclk", CCK_DISPLAY_CLOCK_CONTROL, 81 vlv_clock_get_hpll_vco(drm)); 82} 83 84int vlv_clock_get_gpll(struct drm_device *drm) 85{ 86 return vlv_clock_get_cck(drm, "GPLL ref", CCK_GPLL_CLOCK_CONTROL, 87 vlv_clock_get_czclk(drm)); 88}
~/
Read-only file preview.