On Fri, 17 Feb 2023, Imre Deak <imre.deak@xxxxxxxxx> wrote: > On Fri, Feb 17, 2023 at 12:04:14PM +0200, Jani Nikula wrote: >> On Thu, 16 Feb 2023, Imre Deak <imre.deak@xxxxxxxxx> wrote: >> > On Thu, Feb 16, 2023 at 06:17:39PM +0200, Jani Nikula wrote: >> >> sizeof(struct intel_dmc) > 1024 bytes, allocated on all platforms as >> >> part of struct drm_i915_private, whether they have DMC or not. >> >> >> >> Allocate struct intel_dmc dynamically, and hide all the dmc details >> >> behind an opaque pointer in intel_dmc.c. >> >> >> >> Care must be taken to take into account all cases: DMC not supported on >> >> the platform, DMC supported but not initialized, and DMC initialized but >> >> not loaded. For the second case, we need to move the wakeref out of >> >> struct intel_dmc. >> >> >> >> Cc: Imre Deak <imre.deak@xxxxxxxxx> >> >> Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> >> >> --- >> >> .../gpu/drm/i915/display/intel_display_core.h | 8 ++- >> >> drivers/gpu/drm/i915/display/intel_dmc.c | 50 +++++++++++++++++-- >> >> drivers/gpu/drm/i915/display/intel_dmc.h | 34 +------------ >> >> .../drm/i915/display/intel_modeset_setup.c | 1 + >> >> 4 files changed, 53 insertions(+), 40 deletions(-) >> >> >> >> diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h >> >> index b870f7f47f2b..ff51149c5fcb 100644 >> >> --- a/drivers/gpu/drm/i915/display/intel_display_core.h >> >> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h >> >> @@ -19,7 +19,6 @@ >> >> #include "intel_cdclk.h" >> >> #include "intel_display_limits.h" >> >> #include "intel_display_power.h" >> >> -#include "intel_dmc.h" >> >> #include "intel_dpll_mgr.h" >> >> #include "intel_fbc.h" >> >> #include "intel_global_state.h" >> >> @@ -40,6 +39,7 @@ struct intel_cdclk_vals; >> >> struct intel_color_funcs; >> >> struct intel_crtc; >> >> struct intel_crtc_state; >> >> +struct intel_dmc; >> >> struct intel_dpll_funcs; >> >> struct intel_dpll_mgr; >> >> struct intel_fbdev; >> >> @@ -340,6 +340,11 @@ struct intel_display { >> >> spinlock_t phy_lock; >> >> } dkl; >> >> >> >> + struct { >> >> + struct intel_dmc *dmc; >> >> + intel_wakeref_t wakeref; >> >> + } dmc; >> >> + >> >> struct { >> >> /* VLV/CHV/BXT/GLK DSI MMIO register base address */ >> >> u32 mmio_base; >> >> @@ -467,7 +472,6 @@ struct intel_display { >> >> >> >> /* Grouping using named structs. Keep sorted. */ >> >> struct intel_audio audio; >> >> - struct intel_dmc dmc; >> >> struct intel_dpll dpll; >> >> struct intel_fbc *fbc[I915_MAX_FBCS]; >> >> struct intel_frontbuffer_tracking fb_tracking; >> >> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c >> >> index 1d156ac2eb4c..8428d08e0c3d 100644 >> >> --- a/drivers/gpu/drm/i915/display/intel_dmc.c >> >> +++ b/drivers/gpu/drm/i915/display/intel_dmc.c >> >> @@ -38,9 +38,37 @@ >> >> * low-power state and comes back to normal. >> >> */ >> >> >> >> +enum intel_dmc_id { >> >> + DMC_FW_MAIN = 0, >> >> + DMC_FW_PIPEA, >> >> + DMC_FW_PIPEB, >> >> + DMC_FW_PIPEC, >> >> + DMC_FW_PIPED, >> >> + DMC_FW_MAX >> >> +}; >> >> + >> >> +struct intel_dmc { >> >> + struct drm_i915_private *i915; >> >> + struct work_struct work; >> >> + const char *fw_path; >> >> + u32 max_fw_size; /* bytes */ >> >> + u32 version; >> >> + struct dmc_fw_info { >> >> + u32 mmio_count; >> >> + i915_reg_t mmioaddr[20]; >> >> + u32 mmiodata[20]; >> >> + u32 dmc_offset; >> >> + u32 start_mmioaddr; >> >> + u32 dmc_fw_size; /*dwords */ >> >> + u32 *payload; >> >> + bool present; >> >> + } dmc_info[DMC_FW_MAX]; >> >> +}; >> >> + >> >> +/* Note: This may be NULL. */ >> >> static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915) >> >> { >> >> - return &i915->display.dmc; >> >> + return i915->display.dmc.dmc; >> >> } >> >> >> >> #define DMC_VERSION(major, minor) ((major) << 16 | (minor)) >> >> @@ -937,7 +965,10 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) >> >> if (!HAS_DMC(dev_priv)) >> >> return; >> >> >> >> - dmc = i915_to_dmc(dev_priv); >> >> + dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); >> >> + if (!dmc) >> >> + return; >> > >> > Couldn't driver loading fail in this case instead (simplifying the >> > dmc==NULL checks elsewhere)? >> >> We could fail driver load, yes, but it still wouldn't simplify the NULL >> checks because you could use i915.dmc_firmware_path="" to disable the >> firmware, and what's the point in keeping the 1k memory allocated in >> that case? > > Right, only noticed the same later. But that's only a debug feature so > could be acceptable trade-off for simplicity imo; also the supported but > non-initialized state wouldn't be needed then either. > > It's not a big deal and the check is local to intel_dmc.c, so either way > on the patchset: > Reviewed-by: Imre Deak <imre.deak@xxxxxxxxx> > > (Querying the DMC FW presence in IGT needs to be fixed before merging.) The IGT part seemed harder to fix than just preserving the debugfs output for dmc == NULL. v3 at: https://patchwork.freedesktop.org/series/114431/ > >> BR, >> Jani. >> >> >> > >> >> + >> >> dmc->i915 = dev_priv; >> >> >> >> INIT_WORK(&dmc->work, dmc_load_work_fn); >> >> @@ -991,10 +1022,9 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) >> >> >> >> if (dev_priv->params.dmc_firmware_path) { >> >> if (strlen(dev_priv->params.dmc_firmware_path) == 0) { >> >> - dmc->fw_path = NULL; >> >> drm_info(&dev_priv->drm, >> >> "Disabling DMC firmware and runtime PM\n"); >> >> - return; >> >> + goto out; >> >> } >> >> >> >> dmc->fw_path = dev_priv->params.dmc_firmware_path; >> >> @@ -1003,11 +1033,18 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) >> >> if (!dmc->fw_path) { >> >> drm_dbg_kms(&dev_priv->drm, >> >> "No known DMC firmware for platform, disabling runtime PM\n"); >> >> - return; >> >> + goto out; >> >> } >> >> >> >> + dev_priv->display.dmc.dmc = dmc; >> >> + >> >> drm_dbg_kms(&dev_priv->drm, "Loading %s\n", dmc->fw_path); >> >> schedule_work(&dmc->work); >> >> + >> >> + return; >> >> + >> >> +out: >> >> + kfree(dmc); >> >> } >> >> >> >> /** >> >> @@ -1074,6 +1111,9 @@ void intel_dmc_fini(struct drm_i915_private *dev_priv) >> >> if (dmc) { >> >> for_each_dmc_id(dmc_id) >> >> kfree(dmc->dmc_info[dmc_id].payload); >> >> + >> >> + kfree(dmc); >> >> + dev_priv->display.dmc.dmc = NULL; >> >> } >> >> } >> >> >> >> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h >> >> index b74635497aa7..fd607afff2ef 100644 >> >> --- a/drivers/gpu/drm/i915/display/intel_dmc.h >> >> +++ b/drivers/gpu/drm/i915/display/intel_dmc.h >> >> @@ -6,44 +6,12 @@ >> >> #ifndef __INTEL_DMC_H__ >> >> #define __INTEL_DMC_H__ >> >> >> >> -#include "i915_reg_defs.h" >> >> -#include "intel_wakeref.h" >> >> -#include <linux/workqueue.h> >> >> +#include <linux/types.h> >> >> >> >> struct drm_i915_error_state_buf; >> >> struct drm_i915_private; >> >> - >> >> enum pipe; >> >> >> >> -enum intel_dmc_id { >> >> - DMC_FW_MAIN = 0, >> >> - DMC_FW_PIPEA, >> >> - DMC_FW_PIPEB, >> >> - DMC_FW_PIPEC, >> >> - DMC_FW_PIPED, >> >> - DMC_FW_MAX >> >> -}; >> >> - >> >> -struct intel_dmc { >> >> - struct drm_i915_private *i915; >> >> - struct work_struct work; >> >> - const char *fw_path; >> >> - u32 max_fw_size; /* bytes */ >> >> - u32 version; >> >> - struct dmc_fw_info { >> >> - u32 mmio_count; >> >> - i915_reg_t mmioaddr[20]; >> >> - u32 mmiodata[20]; >> >> - u32 dmc_offset; >> >> - u32 start_mmioaddr; >> >> - u32 dmc_fw_size; /*dwords */ >> >> - u32 *payload; >> >> - bool present; >> >> - } dmc_info[DMC_FW_MAX]; >> >> - >> >> - intel_wakeref_t wakeref; >> >> -}; >> >> - >> >> void intel_dmc_init(struct drm_i915_private *i915); >> >> void intel_dmc_load_program(struct drm_i915_private *i915); >> >> void intel_dmc_disable_program(struct drm_i915_private *i915); >> >> diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c >> >> index 5359b9663a07..42bfd56fcbe4 100644 >> >> --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c >> >> +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c >> >> @@ -22,6 +22,7 @@ >> >> #include "intel_display.h" >> >> #include "intel_display_power.h" >> >> #include "intel_display_types.h" >> >> +#include "intel_dmc.h" >> >> #include "intel_modeset_setup.h" >> >> #include "intel_pch_display.h" >> >> #include "intel_pm.h" >> >> -- >> >> 2.34.1 >> >> >> >> -- >> Jani Nikula, Intel Open Source Graphics Center -- Jani Nikula, Intel Open Source Graphics Center