linux/drivers/gpu/drm/i915/display/intel_cdclk.h

73 lines
3.1 KiB
C
Raw Permalink Normal View History

/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2019 Intel Corporation
*/
#ifndef __INTEL_CDCLK_H__
#define __INTEL_CDCLK_H__
#include <linux/types.h>
enum pipe;
struct intel_atomic_state;
struct intel_cdclk_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_display;
struct intel_cdclk_config {
unsigned int cdclk, vco, ref, bypass;
u8 voltage_level;
drm/i915/xe2lpd: Support MDCLK:CDCLK ratio changes Commit 394b4b7df9f7 ("drm/i915/lnl: Add CDCLK table") and commit 3d3696c0fed1 ("drm/i915/lnl: Start using CDCLK through PLL") started adding support for CDCLK programming support for Xe2LPD. One final piece is missing, which is the programming necessary for changed in the ratio between MDCLK and CDCLK. Let's do that now. BSpec instructs us to update MBUS_CTL and DBUF_CTL_S* registers when the ratio between MDCLK and CDCLK changes. The updates must be done before changing the CDCLK when decreasing the frequency; or after it when increasing the frequency. Ratio-related updates to MBUS_CTL also depend on the state of MBus joining, so they are performed by either CDCLK change sequence or by changes in MBus joining. Since one might happen independently of the other, we need to make sure that both logics see the necessary state values when programming that register. MBus joining logic needs to know the MDCLK:CDCLK ratio and that's already provided via mdclk_cdclk_ratio field of struct intel_dbuf_state. For the CDCLK logic, we need to have something similar: we need to propagate the status of MBus joining to struct intel_cdclk_state. Do that by adding the field joined_mbus to struct intel_cdclk_config. (Preferably, that field would be added to intel_cdclk_state, however currently only intel_cdclk_config is passed down to the functions that do the register programming. We might revisit this decision if we find that refactoring the code to pass the whole intel_cdclk_state is worth it.) Bspec: 68864, 68868, 69090, 69482 Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240312163639.172321-7-gustavo.sousa@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
2024-03-12 13:36:37 -03:00
/* This field is only valid for Xe2LPD and above. */
bool joined_mbus;
};
void intel_cdclk_init_hw(struct intel_display *display);
void intel_cdclk_uninit_hw(struct intel_display *display);
void intel_init_cdclk_hooks(struct intel_display *display);
void intel_update_max_cdclk(struct intel_display *display);
void intel_update_cdclk(struct intel_display *display);
u32 intel_read_rawclk(struct intel_display *display);
bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,
const struct intel_cdclk_config *b);
int intel_mdclk_cdclk_ratio(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config);
bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state);
void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state);
void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state);
void intel_cdclk_dump_config(struct intel_display *display,
const struct intel_cdclk_config *cdclk_config,
const char *context);
int intel_modeset_calc_cdclk(struct intel_atomic_state *state);
void intel_cdclk_get_cdclk(struct intel_display *display,
struct intel_cdclk_config *cdclk_config);
int intel_cdclk_atomic_check(struct intel_atomic_state *state,
bool *need_cdclk_calc);
drm/i915/xe2lpd: Support MDCLK:CDCLK ratio changes Commit 394b4b7df9f7 ("drm/i915/lnl: Add CDCLK table") and commit 3d3696c0fed1 ("drm/i915/lnl: Start using CDCLK through PLL") started adding support for CDCLK programming support for Xe2LPD. One final piece is missing, which is the programming necessary for changed in the ratio between MDCLK and CDCLK. Let's do that now. BSpec instructs us to update MBUS_CTL and DBUF_CTL_S* registers when the ratio between MDCLK and CDCLK changes. The updates must be done before changing the CDCLK when decreasing the frequency; or after it when increasing the frequency. Ratio-related updates to MBUS_CTL also depend on the state of MBus joining, so they are performed by either CDCLK change sequence or by changes in MBus joining. Since one might happen independently of the other, we need to make sure that both logics see the necessary state values when programming that register. MBus joining logic needs to know the MDCLK:CDCLK ratio and that's already provided via mdclk_cdclk_ratio field of struct intel_dbuf_state. For the CDCLK logic, we need to have something similar: we need to propagate the status of MBus joining to struct intel_cdclk_state. Do that by adding the field joined_mbus to struct intel_cdclk_config. (Preferably, that field would be added to intel_cdclk_state, however currently only intel_cdclk_config is passed down to the functions that do the register programming. We might revisit this decision if we find that refactoring the code to pass the whole intel_cdclk_state is worth it.) Bspec: 68864, 68868, 69090, 69482 Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240312163639.172321-7-gustavo.sousa@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
2024-03-12 13:36:37 -03:00
int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool joined_mbus);
struct intel_cdclk_state *
intel_atomic_get_cdclk_state(struct intel_atomic_state *state);
void intel_cdclk_update_hw_state(struct intel_display *display);
void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc);
#define to_intel_cdclk_state(global_state) \
container_of_const((global_state), struct intel_cdclk_state, base)
#define intel_atomic_get_old_cdclk_state(state) \
to_intel_cdclk_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->cdclk.obj))
#define intel_atomic_get_new_cdclk_state(state) \
to_intel_cdclk_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->cdclk.obj))
int intel_cdclk_init(struct intel_display *display);
void intel_cdclk_debugfs_register(struct intel_display *display);
int intel_cdclk_logical(const struct intel_cdclk_state *cdclk_state);
int intel_cdclk_actual(const struct intel_cdclk_state *cdclk_state);
int intel_cdclk_actual_voltage_level(const struct intel_cdclk_state *cdclk_state);
int intel_cdclk_min_cdclk(const struct intel_cdclk_state *cdclk_state, enum pipe pipe);
int intel_cdclk_bw_min_cdclk(const struct intel_cdclk_state *cdclk_state);
bool intel_cdclk_pmdemand_needs_update(struct intel_atomic_state *state);
void intel_cdclk_force_min_cdclk(struct intel_cdclk_state *cdclk_state, int force_min_cdclk);
void intel_cdclk_read_hw(struct intel_display *display);
#endif /* __INTEL_CDCLK_H__ */