From e4ef6503bd4c4ee6fbed2623c50a338dc93d5e9e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 2 Feb 2023 14:04:48 +0200 Subject: drm/i915/dmc: add proper name to dmc id enum and use it Clarify DMC ID usage by adding enum intel_dmc_id name to the enum, and use dmc_id as the variable name for it throughout. Convert a switch-case to if-ladder to avoid warnings about not handling DMC_FW_MAX enumeration constant in the switch-case. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/6912ccb411bb957c68c108b774745dbc7e0cbdc2.1675339447.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 77 ++++++++++++++++---------------- 1 file changed, 38 insertions(+), 39 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 257aa2b7cf20..2cb748900805 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -249,7 +249,7 @@ struct stepping_info { char substepping; }; -static bool has_dmc_id_fw(struct drm_i915_private *i915, int dmc_id) +static bool has_dmc_id_fw(struct drm_i915_private *i915, enum intel_dmc_id dmc_id) { return i915->display.dmc.dmc_info[dmc_id].payload; } @@ -315,26 +315,23 @@ disable_flip_queue_event(struct drm_i915_private *i915, } static bool -get_flip_queue_event_regs(struct drm_i915_private *i915, int dmc_id, +get_flip_queue_event_regs(struct drm_i915_private *i915, enum intel_dmc_id dmc_id, i915_reg_t *ctl_reg, i915_reg_t *htp_reg) { - switch (dmc_id) { - case DMC_FW_MAIN: + if (dmc_id == DMC_FW_MAIN) { if (DISPLAY_VER(i915) == 12) { *ctl_reg = DMC_EVT_CTL(i915, dmc_id, 3); *htp_reg = DMC_EVT_HTP(i915, dmc_id, 3); return true; } - break; - case DMC_FW_PIPEA ... DMC_FW_PIPED: + } else if (dmc_id >= DMC_FW_PIPEA && dmc_id <= DMC_FW_PIPED) { if (IS_DG2(i915)) { *ctl_reg = DMC_EVT_CTL(i915, dmc_id, 2); *htp_reg = DMC_EVT_HTP(i915, dmc_id, 2); return true; } - break; } return false; @@ -343,7 +340,7 @@ get_flip_queue_event_regs(struct drm_i915_private *i915, int dmc_id, static void disable_all_flip_queue_events(struct drm_i915_private *i915) { - int dmc_id; + enum intel_dmc_id dmc_id; /* TODO: check if the following applies to all D13+ platforms. */ if (!IS_DG2(i915) && !IS_TIGERLAKE(i915)) @@ -365,22 +362,22 @@ disable_all_flip_queue_events(struct drm_i915_private *i915) static void disable_all_event_handlers(struct drm_i915_private *i915) { - int id; + enum intel_dmc_id dmc_id; /* TODO: disable the event handlers on pre-GEN12 platforms as well */ if (DISPLAY_VER(i915) < 12) return; - for (id = DMC_FW_MAIN; id < DMC_FW_MAX; id++) { + for (dmc_id = DMC_FW_MAIN; dmc_id < DMC_FW_MAX; dmc_id++) { int handler; - if (!has_dmc_id_fw(i915, id)) + if (!has_dmc_id_fw(i915, dmc_id)) continue; for (handler = 0; handler < DMC_EVENT_HANDLER_COUNT_GEN12; handler++) disable_event_handler(i915, - DMC_EVT_CTL(i915, id, handler), - DMC_EVT_HTP(i915, id, handler)); + DMC_EVT_CTL(i915, dmc_id, handler), + DMC_EVT_HTP(i915, dmc_id, handler)); } } @@ -441,7 +438,8 @@ void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe) void intel_dmc_load_program(struct drm_i915_private *dev_priv) { struct intel_dmc *dmc = &dev_priv->display.dmc; - u32 id, i; + enum intel_dmc_id dmc_id; + u32 i; if (!intel_dmc_has_payload(dev_priv)) return; @@ -454,20 +452,20 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv) preempt_disable(); - for (id = 0; id < DMC_FW_MAX; id++) { - for (i = 0; i < dmc->dmc_info[id].dmc_fw_size; i++) { + for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { intel_de_write_fw(dev_priv, - DMC_PROGRAM(dmc->dmc_info[id].start_mmioaddr, i), - dmc->dmc_info[id].payload[i]); + DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), + dmc->dmc_info[dmc_id].payload[i]); } } preempt_enable(); - for (id = 0; id < DMC_FW_MAX; id++) { - for (i = 0; i < dmc->dmc_info[id].mmio_count; i++) { - intel_de_write(dev_priv, dmc->dmc_info[id].mmioaddr[i], - dmc->dmc_info[id].mmiodata[i]); + for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { + intel_de_write(dev_priv, dmc->dmc_info[dmc_id].mmioaddr[i], + dmc->dmc_info[dmc_id].mmiodata[i]); } } @@ -540,15 +538,16 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, const struct stepping_info *si, u8 package_ver) { - unsigned int i, id; + enum intel_dmc_id dmc_id; + unsigned int i; struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); for (i = 0; i < num_entries; i++) { - id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id; + dmc_id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id; - if (id >= DMC_FW_MAX) { - drm_dbg(&i915->drm, "Unsupported firmware id: %u\n", id); + if (dmc_id >= DMC_FW_MAX) { + drm_dbg(&i915->drm, "Unsupported firmware id: %u\n", dmc_id); continue; } @@ -556,19 +555,19 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, * check for the stepping since we already found a previous FW * for this id. */ - if (dmc->dmc_info[id].present) + if (dmc->dmc_info[dmc_id].present) continue; if (fw_info_matches_stepping(&fw_info[i], si)) { - dmc->dmc_info[id].present = true; - dmc->dmc_info[id].dmc_offset = fw_info[i].offset; + dmc->dmc_info[dmc_id].present = true; + dmc->dmc_info[dmc_id].dmc_offset = fw_info[i].offset; } } } static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, u32 mmio_count, - int header_ver, u8 dmc_id) + int header_ver, enum intel_dmc_id dmc_id) { struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); u32 start_range, end_range; @@ -606,7 +605,7 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, - size_t rem_size, u8 dmc_id) + size_t rem_size, enum intel_dmc_id dmc_id) { struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id]; @@ -802,9 +801,9 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv, struct intel_dmc *dmc = &dev_priv->display.dmc; struct stepping_info display_info = { '*', '*'}; const struct stepping_info *si = intel_get_stepping_info(dev_priv, &display_info); + enum intel_dmc_id dmc_id; u32 readcount = 0; u32 r, offset; - int id; if (!fw) return; @@ -825,18 +824,18 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv, readcount += r; - for (id = 0; id < DMC_FW_MAX; id++) { - if (!dev_priv->display.dmc.dmc_info[id].present) + for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + if (!dev_priv->display.dmc.dmc_info[dmc_id].present) continue; - offset = readcount + dmc->dmc_info[id].dmc_offset * 4; + offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4; if (offset > fw->size) { drm_err(&dev_priv->drm, "Reading beyond the fw_size\n"); continue; } dmc_header = (struct intel_dmc_header_base *)&fw->data[offset]; - parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, id); + parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, dmc_id); } } @@ -1044,7 +1043,7 @@ void intel_dmc_ucode_resume(struct drm_i915_private *dev_priv) */ void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv) { - int id; + enum intel_dmc_id dmc_id; if (!HAS_DMC(dev_priv)) return; @@ -1052,8 +1051,8 @@ void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv) intel_dmc_ucode_suspend(dev_priv); drm_WARN_ON(&dev_priv->drm, dev_priv->display.dmc.wakeref); - for (id = 0; id < DMC_FW_MAX; id++) - kfree(dev_priv->display.dmc.dmc_info[id].payload); + for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) + kfree(dev_priv->display.dmc.dmc_info[dmc_id].payload); } void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m, -- cgit From 23cc452e9b6186d6a8c1ddb380a0193652ea6579 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 2 Feb 2023 14:04:49 +0200 Subject: drm/i915/dmc: add for_each_dmc_id() and use it The loop is duplicated many times, with slightly different ways. Unify. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/8dcaa716093e6fbe75bb69ee7ac715a3f007a523.1675339447.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 2cb748900805..51109cb1d1b5 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -249,6 +249,9 @@ struct stepping_info { char substepping; }; +#define for_each_dmc_id(__dmc_id) \ + for ((__dmc_id) = DMC_FW_MAIN; (__dmc_id) < DMC_FW_MAX; (__dmc_id)++) + static bool has_dmc_id_fw(struct drm_i915_private *i915, enum intel_dmc_id dmc_id) { return i915->display.dmc.dmc_info[dmc_id].payload; @@ -346,7 +349,7 @@ disable_all_flip_queue_events(struct drm_i915_private *i915) if (!IS_DG2(i915) && !IS_TIGERLAKE(i915)) return; - for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + for_each_dmc_id(dmc_id) { i915_reg_t ctl_reg; i915_reg_t htp_reg; @@ -368,7 +371,7 @@ static void disable_all_event_handlers(struct drm_i915_private *i915) if (DISPLAY_VER(i915) < 12) return; - for (dmc_id = DMC_FW_MAIN; dmc_id < DMC_FW_MAX; dmc_id++) { + for_each_dmc_id(dmc_id) { int handler; if (!has_dmc_id_fw(i915, dmc_id)) @@ -452,7 +455,7 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv) preempt_disable(); - for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + for_each_dmc_id(dmc_id) { for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { intel_de_write_fw(dev_priv, DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), @@ -462,7 +465,7 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv) preempt_enable(); - for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + for_each_dmc_id(dmc_id) { for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { intel_de_write(dev_priv, dmc->dmc_info[dmc_id].mmioaddr[i], dmc->dmc_info[dmc_id].mmiodata[i]); @@ -824,7 +827,7 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv, readcount += r; - for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) { + for_each_dmc_id(dmc_id) { if (!dev_priv->display.dmc.dmc_info[dmc_id].present) continue; @@ -1051,7 +1054,7 @@ void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv) intel_dmc_ucode_suspend(dev_priv); drm_WARN_ON(&dev_priv->drm, dev_priv->display.dmc.wakeref); - for (dmc_id = 0; dmc_id < DMC_FW_MAX; dmc_id++) + for_each_dmc_id(dmc_id) kfree(dev_priv->display.dmc.dmc_info[dmc_id].payload); } -- cgit From 3965b8812e173c38b2fd1872dc3e08f436311575 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 2 Feb 2023 14:04:50 +0200 Subject: drm/i915/dmc: remove unnecessary dmc_id validity check The dmc_id comes from for_each_dmc_id() in parse_dmc_fw() -> parse_dmc_fw_header() -> dmc_mmio_addr_sanity_check(). It's valid by definition. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/b4e1c862687f79861a5fa4bfa6797ecda2136fab.1675339447.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 51109cb1d1b5..4cc62b040518 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -576,11 +576,6 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, u32 start_range, end_range; int i; - if (dmc_id >= DMC_FW_MAX) { - drm_warn(&i915->drm, "Unsupported firmware id %u\n", dmc_id); - return false; - } - if (header_ver == 1) { start_range = DMC_MMIO_START_RANGE; end_range = DMC_MMIO_END_RANGE; -- cgit From da97065e4692247767d2a7f2850d193eb2f65229 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 2 Feb 2023 14:04:51 +0200 Subject: drm/i915/dmc: add is_valid_dmc_id() and use it Add a name to the dmc id validity check. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/311213ce328575a95d793a219d4dac7d947086cc.1675339447.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 4cc62b040518..ab0ad8e3e620 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -252,6 +252,11 @@ struct stepping_info { #define for_each_dmc_id(__dmc_id) \ for ((__dmc_id) = DMC_FW_MAIN; (__dmc_id) < DMC_FW_MAX; (__dmc_id)++) +static bool is_valid_dmc_id(enum intel_dmc_id dmc_id) +{ + return dmc_id >= DMC_FW_MAIN && dmc_id < DMC_FW_MAX; +} + static bool has_dmc_id_fw(struct drm_i915_private *i915, enum intel_dmc_id dmc_id) { return i915->display.dmc.dmc_info[dmc_id].payload; @@ -549,7 +554,7 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, for (i = 0; i < num_entries; i++) { dmc_id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id; - if (dmc_id >= DMC_FW_MAX) { + if (!is_valid_dmc_id(dmc_id)) { drm_dbg(&i915->drm, "Unsupported firmware id: %u\n", dmc_id); continue; } -- cgit From 247c7a4cdad87564da49a7879aca2f0653689502 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 2 Feb 2023 14:04:52 +0200 Subject: drm/i915/dmc: check incoming dmc id validity Add validity checks for the dmc ids computed from pipe parameters in intel_dmc_enable_pipe() and intel_dmc_disable_pipe(). It's slightly difficult for humans and static analyzers alike to ensure the resulting dmc ids are within bounds. Just check them and reject invalid ones. Signed-off-by: Jani Nikula Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/6a349c3a2b2def5fc31a48c9844ebd72ee55a22b.1675339447.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index ab0ad8e3e620..3b8e8193d042 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -415,7 +415,9 @@ static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe) { - if (!has_dmc_id_fw(i915, PIPE_TO_DMC_ID(pipe))) + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); + + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(i915, dmc_id)) return; if (DISPLAY_VER(i915) >= 14) @@ -426,7 +428,9 @@ void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe) void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe) { - if (!has_dmc_id_fw(i915, PIPE_TO_DMC_ID(pipe))) + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); + + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(i915, dmc_id)) return; if (DISPLAY_VER(i915) >= 14) -- cgit From ac7215c423a34837b634c90cf29681537bd9998c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Feb 2023 13:06:19 +0200 Subject: drm/i915/dmc: drop "ucode" from function names The ucode part in the init, fini, suspend and resume function names is just unnecessary. Drop it. Cc: Imre Deak Signed-off-by: Jani Nikula Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20230207110619.1821992-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 6 +++--- drivers/gpu/drm/i915/display/intel_dmc.c | 20 ++++++++++---------- drivers/gpu/drm/i915/display/intel_dmc.h | 8 ++++---- drivers/gpu/drm/i915/i915_driver.c | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 166662ade593..a8c91fda40a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8639,7 +8639,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) if (!HAS_DISPLAY(i915)) return 0; - intel_dmc_ucode_init(i915); + intel_dmc_init(i915); i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | @@ -8674,7 +8674,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) return 0; cleanup_vga_client_pw_domain_dmc: - intel_dmc_ucode_fini(i915); + intel_dmc_fini(i915); intel_power_domains_driver_remove(i915); intel_vga_unregister(i915); cleanup_bios: @@ -9000,7 +9000,7 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915) /* part #3: call after gem init */ void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915) { - intel_dmc_ucode_fini(i915); + intel_dmc_fini(i915); intel_power_domains_driver_remove(i915); diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 3b8e8193d042..f70ada2357dc 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -918,13 +918,13 @@ static void dmc_load_work_fn(struct work_struct *work) } /** - * intel_dmc_ucode_init() - initialize the firmware loading. + * intel_dmc_init() - initialize the firmware loading. * @dev_priv: i915 drm device. * * This function is called at the time of loading the display driver to read * firmware from a .bin file and copied into a internal memory. */ -void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) +void intel_dmc_init(struct drm_i915_private *dev_priv) { struct intel_dmc *dmc = &dev_priv->display.dmc; @@ -1002,14 +1002,14 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv) } /** - * intel_dmc_ucode_suspend() - prepare DMC firmware before system suspend + * intel_dmc_suspend() - prepare DMC firmware before system suspend * @dev_priv: i915 drm device * * Prepare the DMC firmware before entering system suspend. This includes * flushing pending work items and releasing any resources acquired during * init. */ -void intel_dmc_ucode_suspend(struct drm_i915_private *dev_priv) +void intel_dmc_suspend(struct drm_i915_private *dev_priv) { if (!HAS_DMC(dev_priv)) return; @@ -1022,13 +1022,13 @@ void intel_dmc_ucode_suspend(struct drm_i915_private *dev_priv) } /** - * intel_dmc_ucode_resume() - init DMC firmware during system resume + * intel_dmc_resume() - init DMC firmware during system resume * @dev_priv: i915 drm device * * Reinitialize the DMC firmware during system resume, reacquiring any - * resources released in intel_dmc_ucode_suspend(). + * resources released in intel_dmc_suspend(). */ -void intel_dmc_ucode_resume(struct drm_i915_private *dev_priv) +void intel_dmc_resume(struct drm_i915_private *dev_priv) { if (!HAS_DMC(dev_priv)) return; @@ -1042,20 +1042,20 @@ void intel_dmc_ucode_resume(struct drm_i915_private *dev_priv) } /** - * intel_dmc_ucode_fini() - unload the DMC firmware. + * intel_dmc_fini() - unload the DMC firmware. * @dev_priv: i915 drm device. * * Firmmware unloading includes freeing the internal memory and reset the * firmware loading status. */ -void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv) +void intel_dmc_fini(struct drm_i915_private *dev_priv) { enum intel_dmc_id dmc_id; if (!HAS_DMC(dev_priv)) return; - intel_dmc_ucode_suspend(dev_priv); + intel_dmc_suspend(dev_priv); drm_WARN_ON(&dev_priv->drm, dev_priv->display.dmc.wakeref); for_each_dmc_id(dmc_id) diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 88eae74dbcf2..c9808bbe7162 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -46,14 +46,14 @@ struct intel_dmc { intel_wakeref_t wakeref; }; -void intel_dmc_ucode_init(struct drm_i915_private *i915); +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); void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe); void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe); -void intel_dmc_ucode_fini(struct drm_i915_private *i915); -void intel_dmc_ucode_suspend(struct drm_i915_private *i915); -void intel_dmc_ucode_resume(struct drm_i915_private *i915); +void intel_dmc_fini(struct drm_i915_private *i915); +void intel_dmc_suspend(struct drm_i915_private *i915); +void intel_dmc_resume(struct drm_i915_private *i915); bool intel_dmc_has_payload(struct drm_i915_private *i915); void intel_dmc_debugfs_register(struct drm_i915_private *i915); void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m, diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 2d65ef0bb615..7f9df11f56dd 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1007,7 +1007,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_suspend_encoders(i915); intel_shutdown_encoders(i915); - intel_dmc_ucode_suspend(i915); + intel_dmc_suspend(i915); i915_gem_suspend(i915); @@ -1099,7 +1099,7 @@ static int i915_drm_suspend(struct drm_device *dev) dev_priv->suspend_count++; - intel_dmc_ucode_suspend(dev_priv); + intel_dmc_suspend(dev_priv); enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); @@ -1220,7 +1220,7 @@ static int i915_drm_resume(struct drm_device *dev) /* Must be called after GGTT is resumed. */ intel_dpt_resume(dev_priv); - intel_dmc_ucode_resume(dev_priv); + intel_dmc_resume(dev_priv); i915_restore_display(dev_priv); intel_pps_unlock_regs_wa(dev_priv); -- cgit From 825f0de2fdda691776b6f45af1d3c9ca3d5ff7fc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Mar 2023 14:29:40 +0200 Subject: drm/i915/power: move dc state members to struct i915_power_domains There's only one reference to the struct intel_dmc members dc_state, target_dc_state, and allowed_dc_mask within intel_dmc.c, begging the question why they are under struct intel_dmc to begin with. Moreover, the only references to i915->display.dmc outside of intel_dmc.c are to these members. They don't belong. Move them from struct intel_dmc to struct i915_power_domains, which seems like a more suitable place. Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230301122944.1298929-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_power.c | 25 ++++++++--------- drivers/gpu/drm/i915/display/intel_display_power.h | 4 +++ .../drm/i915/display/intel_display_power_well.c | 31 +++++++++++++--------- drivers/gpu/drm/i915/display/intel_dmc.c | 3 ++- drivers/gpu/drm/i915/display/intel_dmc.h | 3 --- drivers/gpu/drm/i915/display/intel_psr.c | 3 ++- 6 files changed, 39 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 743b919bb2cf..f085ae971150 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -264,9 +264,10 @@ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, } static u32 -sanitize_target_dc_state(struct drm_i915_private *dev_priv, +sanitize_target_dc_state(struct drm_i915_private *i915, u32 target_dc_state) { + struct i915_power_domains *power_domains = &i915->display.power.domains; static const u32 states[] = { DC_STATE_EN_UPTO_DC6, DC_STATE_EN_UPTO_DC5, @@ -279,7 +280,7 @@ sanitize_target_dc_state(struct drm_i915_private *dev_priv, if (target_dc_state != states[i]) continue; - if (dev_priv->display.dmc.allowed_dc_mask & target_dc_state) + if (power_domains->allowed_dc_mask & target_dc_state) break; target_dc_state = states[i + 1]; @@ -312,7 +313,7 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv, state = sanitize_target_dc_state(dev_priv, state); - if (state == dev_priv->display.dmc.target_dc_state) + if (state == power_domains->target_dc_state) goto unlock; dc_off_enabled = intel_power_well_is_enabled(dev_priv, power_well); @@ -323,7 +324,7 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv, if (!dc_off_enabled) intel_power_well_enable(dev_priv, power_well); - dev_priv->display.dmc.target_dc_state = state; + power_domains->target_dc_state = state; if (!dc_off_enabled) intel_power_well_disable(dev_priv, power_well); @@ -992,10 +993,10 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) dev_priv->params.disable_power_well = sanitize_disable_power_well_option(dev_priv, dev_priv->params.disable_power_well); - dev_priv->display.dmc.allowed_dc_mask = + power_domains->allowed_dc_mask = get_allowed_dc_mask(dev_priv, dev_priv->params.enable_dc); - dev_priv->display.dmc.target_dc_state = + power_domains->target_dc_state = sanitize_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); mutex_init(&power_domains->lock); @@ -2032,7 +2033,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915, * resources as required and also enable deeper system power states * that would be blocked if the firmware was inactive. */ - if (!(i915->display.dmc.allowed_dc_mask & DC_STATE_EN_DC9) && + if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC9) && suspend_mode == I915_DRM_SUSPEND_IDLE && intel_dmc_has_payload(i915)) { intel_display_power_flush_work(i915); @@ -2221,22 +2222,22 @@ void intel_display_power_suspend(struct drm_i915_private *i915) void intel_display_power_resume(struct drm_i915_private *i915) { + struct i915_power_domains *power_domains = &i915->display.power.domains; + if (DISPLAY_VER(i915) >= 11) { bxt_disable_dc9(i915); icl_display_core_init(i915, true); if (intel_dmc_has_payload(i915)) { - if (i915->display.dmc.allowed_dc_mask & - DC_STATE_EN_UPTO_DC6) + if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC6) skl_enable_dc6(i915); - else if (i915->display.dmc.allowed_dc_mask & - DC_STATE_EN_UPTO_DC5) + else if (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5) gen9_enable_dc5(i915); } } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { bxt_disable_dc9(i915); bxt_display_core_init(i915, true); if (intel_dmc_has_payload(i915) && - (i915->display.dmc.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)) + (power_domains->allowed_dc_mask & DC_STATE_EN_UPTO_DC5)) gen9_enable_dc5(i915); } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { hsw_disable_pc8(i915); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 2154d900b1aa..8e96be8e6330 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -137,6 +137,10 @@ struct i915_power_domains { bool display_core_suspended; int power_well_count; + u32 dc_state; + u32 target_dc_state; + u32 allowed_dc_mask; + intel_wakeref_t init_wakeref; intel_wakeref_t disable_wakeref; diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 49042ece9d1c..1676df1dc066 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -691,19 +691,20 @@ static u32 gen9_dc_mask(struct drm_i915_private *dev_priv) return mask; } -void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv) +void gen9_sanitize_dc_state(struct drm_i915_private *i915) { + struct i915_power_domains *power_domains = &i915->display.power.domains; u32 val; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(i915)) return; - val = intel_de_read(dev_priv, DC_STATE_EN) & gen9_dc_mask(dev_priv); + val = intel_de_read(i915, DC_STATE_EN) & gen9_dc_mask(i915); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(&i915->drm, "Resetting DC state tracking from %02x to %02x\n", - dev_priv->display.dmc.dc_state, val); - dev_priv->display.dmc.dc_state = val; + power_domains->dc_state, val); + power_domains->dc_state = val; } /** @@ -731,6 +732,7 @@ void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv) */ void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state) { + struct i915_power_domains *power_domains = &dev_priv->display.power.domains; u32 val; u32 mask; @@ -738,8 +740,8 @@ void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state) return; if (drm_WARN_ON_ONCE(&dev_priv->drm, - state & ~dev_priv->display.dmc.allowed_dc_mask)) - state &= dev_priv->display.dmc.allowed_dc_mask; + state & ~power_domains->allowed_dc_mask)) + state &= power_domains->allowed_dc_mask; val = intel_de_read(dev_priv, DC_STATE_EN); mask = gen9_dc_mask(dev_priv); @@ -747,16 +749,16 @@ void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state) val & mask, state); /* Check if DMC is ignoring our DC state requests */ - if ((val & mask) != dev_priv->display.dmc.dc_state) + if ((val & mask) != power_domains->dc_state) drm_err(&dev_priv->drm, "DC state mismatch (0x%x -> 0x%x)\n", - dev_priv->display.dmc.dc_state, val & mask); + power_domains->dc_state, val & mask); val &= ~mask; val |= state; gen9_write_dc_state(dev_priv, val); - dev_priv->display.dmc.dc_state = val & mask; + power_domains->dc_state = val & mask; } static void tgl_enable_dc3co(struct drm_i915_private *dev_priv) @@ -944,9 +946,10 @@ static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv) void gen9_disable_dc_states(struct drm_i915_private *dev_priv) { + struct i915_power_domains *power_domains = &dev_priv->display.power.domains; struct intel_cdclk_config cdclk_config = {}; - if (dev_priv->display.dmc.target_dc_state == DC_STATE_EN_DC3CO) { + if (power_domains->target_dc_state == DC_STATE_EN_DC3CO) { tgl_disable_dc3co(dev_priv); return; } @@ -985,10 +988,12 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, static void gen9_dc_off_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { + struct i915_power_domains *power_domains = &dev_priv->display.power.domains; + if (!intel_dmc_has_payload(dev_priv)) return; - switch (dev_priv->display.dmc.target_dc_state) { + switch (power_domains->target_dc_state) { case DC_STATE_EN_DC3CO: tgl_enable_dc3co(dev_priv); break; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index f70ada2357dc..ab4fdedd4c5f 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -449,6 +449,7 @@ void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe) */ void intel_dmc_load_program(struct drm_i915_private *dev_priv) { + struct i915_power_domains *power_domains = &dev_priv->display.power.domains; struct intel_dmc *dmc = &dev_priv->display.dmc; enum intel_dmc_id dmc_id; u32 i; @@ -481,7 +482,7 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv) } } - dev_priv->display.dmc.dc_state = 0; + power_domains->dc_state = 0; gen9_set_dc_state_debugmask(dev_priv); diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index c9808bbe7162..90910cecc2f6 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -40,9 +40,6 @@ struct intel_dmc { bool present; } dmc_info[DMC_FW_MAX]; - u32 dc_state; - u32 target_dc_state; - u32 allowed_dc_mask; intel_wakeref_t wakeref; }; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 93b4e1ce7615..44610b20cd29 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -690,6 +690,7 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, { const u32 crtc_vdisplay = crtc_state->uapi.adjusted_mode.crtc_vdisplay; struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct i915_power_domains *power_domains = &dev_priv->display.power.domains; u32 exit_scanlines; /* @@ -706,7 +707,7 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, if (crtc_state->enable_psr2_sel_fetch) return; - if (!(dev_priv->display.dmc.allowed_dc_mask & DC_STATE_EN_DC3CO)) + if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC3CO)) return; if (!dc3co_is_pipe_port_compatible(intel_dp, crtc_state)) -- cgit From fe00866c65602e94c1b6b3d3efcea3633330b02f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Mar 2023 14:29:41 +0200 Subject: drm/i915/dmc: use has_dmc_id_fw() instead of poking dmc->dmc_info directly This will help in follow-up changes. Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230301122944.1298929-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index ab4fdedd4c5f..599fb92a5161 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -1098,12 +1098,12 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) seq_printf(m, "Pipe A fw needed: %s\n", str_yes_no(GRAPHICS_VER(i915) >= 12)); seq_printf(m, "Pipe A fw loaded: %s\n", - str_yes_no(dmc->dmc_info[DMC_FW_PIPEA].payload)); + str_yes_no(has_dmc_id_fw(i915, DMC_FW_PIPEA))); seq_printf(m, "Pipe B fw needed: %s\n", str_yes_no(IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)); seq_printf(m, "Pipe B fw loaded: %s\n", - str_yes_no(dmc->dmc_info[DMC_FW_PIPEB].payload)); + str_yes_no(has_dmc_id_fw(i915, DMC_FW_PIPEB))); if (!intel_dmc_has_payload(i915)) goto out; -- cgit From 1b28c1c789d0c11be213bb5d892f9a094ab8e201 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Mar 2023 14:29:42 +0200 Subject: drm/i915/dmc: add i915_to_dmc() and dmc->i915 and use them Start preparing for dynamically allocated struct intel_dmc by adding i915_to_dmc() and dmc->i915, and using them. Take the future NULL dmc pointer into account already now, and add separate logging for initialization in the DMC debugfs. v3: - Obtain runtime pm reference first (Imre) v2: - Don't reduce debugfs output (Imre) Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230301122944.1298929-3-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 94 +++++++++++++++++++------------- drivers/gpu/drm/i915/display/intel_dmc.h | 1 + 2 files changed, 56 insertions(+), 39 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 599fb92a5161..acd792480aba 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -38,6 +38,11 @@ * low-power state and comes back to normal. */ +static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915) +{ + return &i915->display.dmc; +} + #define DMC_VERSION(major, minor) ((major) << 16 | (minor)) #define DMC_VERSION_MAJOR(version) ((version) >> 16) #define DMC_VERSION_MINOR(version) ((version) & 0xffff) @@ -259,7 +264,9 @@ static bool is_valid_dmc_id(enum intel_dmc_id dmc_id) static bool has_dmc_id_fw(struct drm_i915_private *i915, enum intel_dmc_id dmc_id) { - return i915->display.dmc.dmc_info[dmc_id].payload; + struct intel_dmc *dmc = i915_to_dmc(i915); + + return dmc && dmc->dmc_info[dmc_id].payload; } bool intel_dmc_has_payload(struct drm_i915_private *i915) @@ -450,7 +457,7 @@ void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe) void intel_dmc_load_program(struct drm_i915_private *dev_priv) { struct i915_power_domains *power_domains = &dev_priv->display.power.domains; - struct intel_dmc *dmc = &dev_priv->display.dmc; + struct intel_dmc *dmc = i915_to_dmc(dev_priv); enum intel_dmc_id dmc_id; u32 i; @@ -515,8 +522,11 @@ void intel_dmc_disable_program(struct drm_i915_private *i915) void assert_dmc_loaded(struct drm_i915_private *i915) { - drm_WARN_ONCE(&i915->drm, - !intel_de_read(i915, DMC_PROGRAM(i915->display.dmc.dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), + struct intel_dmc *dmc = i915_to_dmc(i915); + + drm_WARN_ONCE(&i915->drm, !dmc, "DMC not initialized\n"); + drm_WARN_ONCE(&i915->drm, dmc && + !intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), "DMC program storage start is NULL\n"); drm_WARN_ONCE(&i915->drm, !intel_de_read(i915, DMC_SSP_BASE), "DMC SSP Base Not fine\n"); @@ -551,11 +561,10 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc, const struct stepping_info *si, u8 package_ver) { + struct drm_i915_private *i915 = dmc->i915; enum intel_dmc_id dmc_id; unsigned int i; - struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); - for (i = 0; i < num_entries; i++) { dmc_id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id; @@ -582,7 +591,7 @@ static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, const u32 *mmioaddr, u32 mmio_count, int header_ver, enum intel_dmc_id dmc_id) { - struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); + struct drm_i915_private *i915 = dmc->i915; u32 start_range, end_range; int i; @@ -615,7 +624,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc, const struct intel_dmc_header_base *dmc_header, size_t rem_size, enum intel_dmc_id dmc_id) { - struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); + struct drm_i915_private *i915 = dmc->i915; struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id]; unsigned int header_len_bytes, dmc_header_size, payload_size, i; const u32 *mmioaddr, *mmiodata; @@ -726,7 +735,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc, const struct stepping_info *si, size_t rem_size) { - struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); + struct drm_i915_private *i915 = dmc->i915; u32 package_size = sizeof(struct intel_package_header); u32 num_entries, max_entries; const struct intel_fw_info *fw_info; @@ -780,7 +789,7 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc, struct intel_css_header *css_header, size_t rem_size) { - struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), display.dmc); + struct drm_i915_private *i915 = dmc->i915; if (rem_size < sizeof(struct intel_css_header)) { drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); @@ -800,13 +809,12 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc, return sizeof(struct intel_css_header); } -static void parse_dmc_fw(struct drm_i915_private *dev_priv, - const struct firmware *fw) +static void parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) { + struct drm_i915_private *dev_priv = dmc->i915; struct intel_css_header *css_header; struct intel_package_header *package_header; struct intel_dmc_header_base *dmc_header; - struct intel_dmc *dmc = &dev_priv->display.dmc; struct stepping_info display_info = { '*', '*'}; const struct stepping_info *si = intel_get_stepping_info(dev_priv, &display_info); enum intel_dmc_id dmc_id; @@ -833,7 +841,7 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv, readcount += r; for_each_dmc_id(dmc_id) { - if (!dev_priv->display.dmc.dmc_info[dmc_id].present) + if (!dmc->dmc_info[dmc_id].present) continue; offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4; @@ -872,16 +880,13 @@ static const char *dmc_fallback_path(struct drm_i915_private *i915) static void dmc_load_work_fn(struct work_struct *work) { - struct drm_i915_private *dev_priv; - struct intel_dmc *dmc; + struct intel_dmc *dmc = container_of(work, typeof(*dmc), work); + struct drm_i915_private *dev_priv = dmc->i915; const struct firmware *fw = NULL; const char *fallback_path; int err; - dev_priv = container_of(work, typeof(*dev_priv), display.dmc.work); - dmc = &dev_priv->display.dmc; - - err = request_firmware(&fw, dev_priv->display.dmc.fw_path, dev_priv->drm.dev); + err = request_firmware(&fw, dmc->fw_path, dev_priv->drm.dev); if (err == -ENOENT && !dev_priv->params.dmc_firmware_path) { fallback_path = dmc_fallback_path(dev_priv); @@ -892,11 +897,11 @@ static void dmc_load_work_fn(struct work_struct *work) fallback_path); err = request_firmware(&fw, fallback_path, dev_priv->drm.dev); if (err == 0) - dev_priv->display.dmc.fw_path = fallback_path; + dmc->fw_path = fallback_path; } } - parse_dmc_fw(dev_priv, fw); + parse_dmc_fw(dmc, fw); if (intel_dmc_has_payload(dev_priv)) { intel_dmc_load_program(dev_priv); @@ -904,7 +909,7 @@ static void dmc_load_work_fn(struct work_struct *work) drm_info(&dev_priv->drm, "Finished loading DMC firmware %s (v%u.%u)\n", - dev_priv->display.dmc.fw_path, DMC_VERSION_MAJOR(dmc->version), + dmc->fw_path, DMC_VERSION_MAJOR(dmc->version), DMC_VERSION_MINOR(dmc->version)); } else { drm_notice(&dev_priv->drm, @@ -927,9 +932,7 @@ static void dmc_load_work_fn(struct work_struct *work) */ void intel_dmc_init(struct drm_i915_private *dev_priv) { - struct intel_dmc *dmc = &dev_priv->display.dmc; - - INIT_WORK(&dev_priv->display.dmc.work, dmc_load_work_fn); + struct intel_dmc *dmc; if (!HAS_DMC(dev_priv)) return; @@ -944,6 +947,11 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); + dmc = i915_to_dmc(dev_priv); + dmc->i915 = dev_priv; + + INIT_WORK(&dmc->work, dmc_load_work_fn); + if (IS_DG2(dev_priv)) { dmc->fw_path = DG2_DMC_PATH; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; @@ -999,7 +1007,7 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) } drm_dbg_kms(&dev_priv->drm, "Loading %s\n", dmc->fw_path); - schedule_work(&dev_priv->display.dmc.work); + schedule_work(&dmc->work); } /** @@ -1012,10 +1020,13 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) */ void intel_dmc_suspend(struct drm_i915_private *dev_priv) { + struct intel_dmc *dmc = i915_to_dmc(dev_priv); + if (!HAS_DMC(dev_priv)) return; - flush_work(&dev_priv->display.dmc.work); + if (dmc) + flush_work(&dmc->work); /* Drop the reference held in case DMC isn't loaded. */ if (!intel_dmc_has_payload(dev_priv)) @@ -1051,6 +1062,7 @@ void intel_dmc_resume(struct drm_i915_private *dev_priv) */ void intel_dmc_fini(struct drm_i915_private *dev_priv) { + struct intel_dmc *dmc = i915_to_dmc(dev_priv); enum intel_dmc_id dmc_id; if (!HAS_DMC(dev_priv)) @@ -1059,42 +1071,45 @@ void intel_dmc_fini(struct drm_i915_private *dev_priv) intel_dmc_suspend(dev_priv); drm_WARN_ON(&dev_priv->drm, dev_priv->display.dmc.wakeref); - for_each_dmc_id(dmc_id) - kfree(dev_priv->display.dmc.dmc_info[dmc_id].payload); + if (dmc) { + for_each_dmc_id(dmc_id) + kfree(dmc->dmc_info[dmc_id].payload); + } } void intel_dmc_print_error_state(struct drm_i915_error_state_buf *m, struct drm_i915_private *i915) { - struct intel_dmc *dmc = &i915->display.dmc; + struct intel_dmc *dmc = i915_to_dmc(i915); if (!HAS_DMC(i915)) return; + i915_error_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); i915_error_printf(m, "DMC loaded: %s\n", str_yes_no(intel_dmc_has_payload(i915))); - i915_error_printf(m, "DMC fw version: %d.%d\n", - DMC_VERSION_MAJOR(dmc->version), - DMC_VERSION_MINOR(dmc->version)); + if (dmc) + i915_error_printf(m, "DMC fw version: %d.%d\n", + DMC_VERSION_MAJOR(dmc->version), + DMC_VERSION_MINOR(dmc->version)); } static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) { struct drm_i915_private *i915 = m->private; + struct intel_dmc *dmc = i915_to_dmc(i915); intel_wakeref_t wakeref; - struct intel_dmc *dmc; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; if (!HAS_DMC(i915)) return -ENODEV; - dmc = &i915->display.dmc; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); seq_printf(m, "fw loaded: %s\n", str_yes_no(intel_dmc_has_payload(i915))); - seq_printf(m, "path: %s\n", dmc->fw_path); + seq_printf(m, "path: %s\n", dmc ? dmc->fw_path : "N/A"); seq_printf(m, "Pipe A fw needed: %s\n", str_yes_no(GRAPHICS_VER(i915) >= 12)); seq_printf(m, "Pipe A fw loaded: %s\n", @@ -1137,9 +1152,10 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) seq_printf(m, "DC5 -> DC6 count: %d\n", intel_de_read(i915, dc6_reg)); -out: seq_printf(m, "program base: 0x%08x\n", intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0))); + +out: seq_printf(m, "ssp base: 0x%08x\n", intel_de_read(i915, DMC_SSP_BASE)); seq_printf(m, "htp: 0x%08x\n", intel_de_read(i915, DMC_HTP_SKL)); diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 90910cecc2f6..b74635497aa7 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -25,6 +25,7 @@ enum intel_dmc_id { }; struct intel_dmc { + struct drm_i915_private *i915; struct work_struct work; const char *fw_path; u32 max_fw_size; /* bytes */ -- cgit From e81a3c12b88ab685ce10482c3f6d5aa46f08a6fa Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Mar 2023 14:29:43 +0200 Subject: drm/i915/dmc: allocate dmc structure dynamically 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. v2: - Rebase to kzalloc dmc after runtime pm get (Imre) Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230301122944.1298929-4-jani.nikula@intel.com --- drivers/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 +-------------- drivers/gpu/drm/i915/display/intel_modeset_setup.c | 1 + 4 files changed, 53 insertions(+), 40 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 631a7b17899e..fdab7bb93a7d 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 acd792480aba..302a465ceb1f 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)) @@ -947,7 +975,10 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) */ intel_dmc_runtime_pm_get(dev_priv); - dmc = i915_to_dmc(dev_priv); + dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); + if (!dmc) + return; + 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 +#include 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 7ff083ec2d1d..1d0c9e247c42 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_fifo_underrun.h" #include "intel_modeset_setup.h" #include "intel_pch_display.h" -- cgit From bd5a7886f5ff6899170f3acd85f57c0f43d0371e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Mar 2023 14:29:44 +0200 Subject: drm/i915/dmc: mass rename dev_priv to i915 Follow the contemporary convention for struct drm_i915_private * naming. Cc: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230301122944.1298929-5-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 166 +++++++++++++++---------------- 1 file changed, 81 insertions(+), 85 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 302a465ceb1f..6b162f77340e 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -313,12 +313,12 @@ intel_get_stepping_info(struct drm_i915_private *i915, return si; } -static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) +static void gen9_set_dc_state_debugmask(struct drm_i915_private *i915) { /* The below bit doesn't need to be cleared ever afterwards */ - intel_de_rmw(dev_priv, DC_STATE_DEBUG, 0, + intel_de_rmw(i915, DC_STATE_DEBUG, 0, DC_STATE_DEBUG_MASK_CORES | DC_STATE_DEBUG_MASK_MEMORY_UP); - intel_de_posting_read(dev_priv, DC_STATE_DEBUG); + intel_de_posting_read(i915, DC_STATE_DEBUG); } static void disable_event_handler(struct drm_i915_private *i915, @@ -476,33 +476,33 @@ void intel_dmc_disable_pipe(struct drm_i915_private *i915, enum pipe pipe) /** * intel_dmc_load_program() - write the firmware from memory to register. - * @dev_priv: i915 drm device. + * @i915: i915 drm device. * * DMC firmware is read from a .bin file and kept in internal memory one time. * Everytime display comes back from low power state this function is called to * copy the firmware from internal memory to registers. */ -void intel_dmc_load_program(struct drm_i915_private *dev_priv) +void intel_dmc_load_program(struct drm_i915_private *i915) { - struct i915_power_domains *power_domains = &dev_priv->display.power.domains; - struct intel_dmc *dmc = i915_to_dmc(dev_priv); + struct i915_power_domains *power_domains = &i915->display.power.domains; + struct intel_dmc *dmc = i915_to_dmc(i915); enum intel_dmc_id dmc_id; u32 i; - if (!intel_dmc_has_payload(dev_priv)) + if (!intel_dmc_has_payload(i915)) return; - pipedmc_clock_gating_wa(dev_priv, true); + pipedmc_clock_gating_wa(i915, true); - disable_all_event_handlers(dev_priv); + disable_all_event_handlers(i915); - assert_rpm_wakelock_held(&dev_priv->runtime_pm); + assert_rpm_wakelock_held(&i915->runtime_pm); preempt_disable(); for_each_dmc_id(dmc_id) { for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { - intel_de_write_fw(dev_priv, + intel_de_write_fw(i915, DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), dmc->dmc_info[dmc_id].payload[i]); } @@ -512,23 +512,23 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv) for_each_dmc_id(dmc_id) { for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { - intel_de_write(dev_priv, dmc->dmc_info[dmc_id].mmioaddr[i], + intel_de_write(i915, dmc->dmc_info[dmc_id].mmioaddr[i], dmc->dmc_info[dmc_id].mmiodata[i]); } } power_domains->dc_state = 0; - gen9_set_dc_state_debugmask(dev_priv); + gen9_set_dc_state_debugmask(i915); /* * Flip queue events need to be disabled before enabling DC5/6. * i915 doesn't use the flip queue feature, so disable it already * here. */ - disable_all_flip_queue_events(dev_priv); + disable_all_flip_queue_events(i915); - pipedmc_clock_gating_wa(dev_priv, false); + pipedmc_clock_gating_wa(i915, false); } /** @@ -839,12 +839,12 @@ static u32 parse_dmc_fw_css(struct intel_dmc *dmc, static void parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) { - struct drm_i915_private *dev_priv = dmc->i915; + struct drm_i915_private *i915 = dmc->i915; struct intel_css_header *css_header; struct intel_package_header *package_header; struct intel_dmc_header_base *dmc_header; struct stepping_info display_info = { '*', '*'}; - const struct stepping_info *si = intel_get_stepping_info(dev_priv, &display_info); + const struct stepping_info *si = intel_get_stepping_info(i915, &display_info); enum intel_dmc_id dmc_id; u32 readcount = 0; u32 r, offset; @@ -874,7 +874,7 @@ static void parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4; if (offset > fw->size) { - drm_err(&dev_priv->drm, "Reading beyond the fw_size\n"); + drm_err(&i915->drm, "Reading beyond the fw_size\n"); continue; } @@ -883,19 +883,18 @@ static void parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) } } -static void intel_dmc_runtime_pm_get(struct drm_i915_private *dev_priv) +static void intel_dmc_runtime_pm_get(struct drm_i915_private *i915) { - drm_WARN_ON(&dev_priv->drm, dev_priv->display.dmc.wakeref); - dev_priv->display.dmc.wakeref = - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); + drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref); + i915->display.dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); } -static void intel_dmc_runtime_pm_put(struct drm_i915_private *dev_priv) +static void intel_dmc_runtime_pm_put(struct drm_i915_private *i915) { intel_wakeref_t wakeref __maybe_unused = - fetch_and_zero(&dev_priv->display.dmc.wakeref); + fetch_and_zero(&i915->display.dmc.wakeref); - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); + intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref); } static const char *dmc_fallback_path(struct drm_i915_private *i915) @@ -909,21 +908,19 @@ static const char *dmc_fallback_path(struct drm_i915_private *i915) static void dmc_load_work_fn(struct work_struct *work) { struct intel_dmc *dmc = container_of(work, typeof(*dmc), work); - struct drm_i915_private *dev_priv = dmc->i915; + struct drm_i915_private *i915 = dmc->i915; const struct firmware *fw = NULL; const char *fallback_path; int err; - err = request_firmware(&fw, dmc->fw_path, dev_priv->drm.dev); + err = request_firmware(&fw, dmc->fw_path, i915->drm.dev); - if (err == -ENOENT && !dev_priv->params.dmc_firmware_path) { - fallback_path = dmc_fallback_path(dev_priv); + if (err == -ENOENT && !i915->params.dmc_firmware_path) { + fallback_path = dmc_fallback_path(i915); if (fallback_path) { - drm_dbg_kms(&dev_priv->drm, - "%s not found, falling back to %s\n", - dmc->fw_path, - fallback_path); - err = request_firmware(&fw, fallback_path, dev_priv->drm.dev); + drm_dbg_kms(&i915->drm, "%s not found, falling back to %s\n", + dmc->fw_path, fallback_path); + err = request_firmware(&fw, fallback_path, i915->drm.dev); if (err == 0) dmc->fw_path = fallback_path; } @@ -931,20 +928,19 @@ static void dmc_load_work_fn(struct work_struct *work) parse_dmc_fw(dmc, fw); - if (intel_dmc_has_payload(dev_priv)) { - intel_dmc_load_program(dev_priv); - intel_dmc_runtime_pm_put(dev_priv); + if (intel_dmc_has_payload(i915)) { + intel_dmc_load_program(i915); + intel_dmc_runtime_pm_put(i915); - drm_info(&dev_priv->drm, - "Finished loading DMC firmware %s (v%u.%u)\n", + drm_info(&i915->drm, "Finished loading DMC firmware %s (v%u.%u)\n", dmc->fw_path, DMC_VERSION_MAJOR(dmc->version), DMC_VERSION_MINOR(dmc->version)); } else { - drm_notice(&dev_priv->drm, + drm_notice(&i915->drm, "Failed to load DMC firmware %s." " Disabling runtime power management.\n", dmc->fw_path); - drm_notice(&dev_priv->drm, "DMC firmware homepage: %s", + drm_notice(&i915->drm, "DMC firmware homepage: %s", INTEL_UC_FIRMWARE_URL); } @@ -953,16 +949,16 @@ static void dmc_load_work_fn(struct work_struct *work) /** * intel_dmc_init() - initialize the firmware loading. - * @dev_priv: i915 drm device. + * @i915: i915 drm device. * * This function is called at the time of loading the display driver to read * firmware from a .bin file and copied into a internal memory. */ -void intel_dmc_init(struct drm_i915_private *dev_priv) +void intel_dmc_init(struct drm_i915_private *i915) { struct intel_dmc *dmc; - if (!HAS_DMC(dev_priv)) + if (!HAS_DMC(i915)) return; /* @@ -973,72 +969,72 @@ void intel_dmc_init(struct drm_i915_private *dev_priv) * suspend as runtime suspend *requires* a working DMC for whatever * reason. */ - intel_dmc_runtime_pm_get(dev_priv); + intel_dmc_runtime_pm_get(i915); dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); if (!dmc) return; - dmc->i915 = dev_priv; + dmc->i915 = i915; INIT_WORK(&dmc->work, dmc_load_work_fn); - if (IS_DG2(dev_priv)) { + if (IS_DG2(i915)) { dmc->fw_path = DG2_DMC_PATH; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; - } else if (IS_ALDERLAKE_P(dev_priv)) { + } else if (IS_ALDERLAKE_P(i915)) { dmc->fw_path = ADLP_DMC_PATH; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; - } else if (IS_ALDERLAKE_S(dev_priv)) { + } else if (IS_ALDERLAKE_S(i915)) { dmc->fw_path = ADLS_DMC_PATH; dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (IS_DG1(dev_priv)) { + } else if (IS_DG1(i915)) { dmc->fw_path = DG1_DMC_PATH; dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (IS_ROCKETLAKE(dev_priv)) { + } else if (IS_ROCKETLAKE(i915)) { dmc->fw_path = RKL_DMC_PATH; dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (IS_TIGERLAKE(dev_priv)) { + } else if (IS_TIGERLAKE(i915)) { dmc->fw_path = TGL_DMC_PATH; dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (DISPLAY_VER(dev_priv) == 11) { + } else if (DISPLAY_VER(i915) == 11) { dmc->fw_path = ICL_DMC_PATH; dmc->max_fw_size = ICL_DMC_MAX_FW_SIZE; - } else if (IS_GEMINILAKE(dev_priv)) { + } else if (IS_GEMINILAKE(i915)) { dmc->fw_path = GLK_DMC_PATH; dmc->max_fw_size = GLK_DMC_MAX_FW_SIZE; - } else if (IS_KABYLAKE(dev_priv) || - IS_COFFEELAKE(dev_priv) || - IS_COMETLAKE(dev_priv)) { + } else if (IS_KABYLAKE(i915) || + IS_COFFEELAKE(i915) || + IS_COMETLAKE(i915)) { dmc->fw_path = KBL_DMC_PATH; dmc->max_fw_size = KBL_DMC_MAX_FW_SIZE; - } else if (IS_SKYLAKE(dev_priv)) { + } else if (IS_SKYLAKE(i915)) { dmc->fw_path = SKL_DMC_PATH; dmc->max_fw_size = SKL_DMC_MAX_FW_SIZE; - } else if (IS_BROXTON(dev_priv)) { + } else if (IS_BROXTON(i915)) { dmc->fw_path = BXT_DMC_PATH; dmc->max_fw_size = BXT_DMC_MAX_FW_SIZE; } - if (dev_priv->params.dmc_firmware_path) { - if (strlen(dev_priv->params.dmc_firmware_path) == 0) { - drm_info(&dev_priv->drm, + if (i915->params.dmc_firmware_path) { + if (strlen(i915->params.dmc_firmware_path) == 0) { + drm_info(&i915->drm, "Disabling DMC firmware and runtime PM\n"); goto out; } - dmc->fw_path = dev_priv->params.dmc_firmware_path; + dmc->fw_path = i915->params.dmc_firmware_path; } if (!dmc->fw_path) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(&i915->drm, "No known DMC firmware for platform, disabling runtime PM\n"); goto out; } - dev_priv->display.dmc.dmc = dmc; + i915->display.dmc.dmc = dmc; - drm_dbg_kms(&dev_priv->drm, "Loading %s\n", dmc->fw_path); + drm_dbg_kms(&i915->drm, "Loading %s\n", dmc->fw_path); schedule_work(&dmc->work); return; @@ -1049,71 +1045,71 @@ out: /** * intel_dmc_suspend() - prepare DMC firmware before system suspend - * @dev_priv: i915 drm device + * @i915: i915 drm device * * Prepare the DMC firmware before entering system suspend. This includes * flushing pending work items and releasing any resources acquired during * init. */ -void intel_dmc_suspend(struct drm_i915_private *dev_priv) +void intel_dmc_suspend(struct drm_i915_private *i915) { - struct intel_dmc *dmc = i915_to_dmc(dev_priv); + struct intel_dmc *dmc = i915_to_dmc(i915); - if (!HAS_DMC(dev_priv)) + if (!HAS_DMC(i915)) return; if (dmc) flush_work(&dmc->work); /* Drop the reference held in case DMC isn't loaded. */ - if (!intel_dmc_has_payload(dev_priv)) - intel_dmc_runtime_pm_put(dev_priv); + if (!intel_dmc_has_payload(i915)) + intel_dmc_runtime_pm_put(i915); } /** * intel_dmc_resume() - init DMC firmware during system resume - * @dev_priv: i915 drm device + * @i915: i915 drm device * * Reinitialize the DMC firmware during system resume, reacquiring any * resources released in intel_dmc_suspend(). */ -void intel_dmc_resume(struct drm_i915_private *dev_priv) +void intel_dmc_resume(struct drm_i915_private *i915) { - if (!HAS_DMC(dev_priv)) + if (!HAS_DMC(i915)) return; /* * Reacquire the reference to keep RPM disabled in case DMC isn't * loaded. */ - if (!intel_dmc_has_payload(dev_priv)) - intel_dmc_runtime_pm_get(dev_priv); + if (!intel_dmc_has_payload(i915)) + intel_dmc_runtime_pm_get(i915); } /** * intel_dmc_fini() - unload the DMC firmware. - * @dev_priv: i915 drm device. + * @i915: i915 drm device. * * Firmmware unloading includes freeing the internal memory and reset the * firmware loading status. */ -void intel_dmc_fini(struct drm_i915_private *dev_priv) +void intel_dmc_fini(struct drm_i915_private *i915) { - struct intel_dmc *dmc = i915_to_dmc(dev_priv); + struct intel_dmc *dmc = i915_to_dmc(i915); enum intel_dmc_id dmc_id; - if (!HAS_DMC(dev_priv)) + if (!HAS_DMC(i915)) return; - intel_dmc_suspend(dev_priv); - drm_WARN_ON(&dev_priv->drm, dev_priv->display.dmc.wakeref); + intel_dmc_suspend(i915); + drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref); if (dmc) { for_each_dmc_id(dmc_id) kfree(dmc->dmc_info[dmc_id].payload); kfree(dmc); - dev_priv->display.dmc.dmc = NULL; + i915->display.dmc.dmc = NULL; } } -- cgit From 0188be507b973e36f637ba010a369057c8cb7282 Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Wed, 1 Mar 2023 12:10:49 -0800 Subject: drm/i915/mtl: Fix Wa_16015201720 implementation The commit 2357f2b271ad ("drm/i915/mtl: Initial display workarounds") extended the workaround Wa_16015201720 to MTL. However the registers that the original WA implemented moved for MTL. Implement the workaround with the correct register. v3: Skip clock gating for pipe C, D DMC's and fix the title Fixes: 2357f2b271ad ("drm/i915/mtl: Initial display workarounds") Cc: Matt Atwood Cc: Lucas De Marchi Signed-off-by: Radhakrishna Sripada Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20230301201053.928709-2-radhakrishna.sripada@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 26 +++++++++++++++++++++----- drivers/gpu/drm/i915/i915_reg.h | 8 +++++--- 2 files changed, 26 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 6b162f77340e..ae247495d9a2 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -424,15 +424,12 @@ static void disable_all_event_handlers(struct drm_i915_private *i915) } } -static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) +static void adlp_pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) { enum pipe pipe; - if (DISPLAY_VER(i915) < 13) - return; - /* - * Wa_16015201720:adl-p,dg2, mtl + * Wa_16015201720:adl-p,dg2 * The WA requires clock gating to be disabled all the time * for pipe A and B. * For pipe C and D clock gating needs to be disabled only @@ -448,6 +445,25 @@ static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) PIPEDMC_GATING_DIS, 0); } +static void mtl_pipedmc_clock_gating_wa(struct drm_i915_private *i915) +{ + /* + * Wa_16015201720 + * The WA requires clock gating to be disabled all the time + * for pipe A and B. + */ + intel_de_rmw(i915, GEN9_CLKGATE_DIS_0, 0, + MTL_PIPEDMC_GATING_DIS_A | MTL_PIPEDMC_GATING_DIS_B); +} + +static void pipedmc_clock_gating_wa(struct drm_i915_private *i915, bool enable) +{ + if (DISPLAY_VER(i915) >= 14 && enable) + mtl_pipedmc_clock_gating_wa(i915); + else if (DISPLAY_VER(i915) == 13) + adlp_pipedmc_clock_gating_wa(i915, enable); +} + void intel_dmc_enable_pipe(struct drm_i915_private *i915, enum pipe pipe) { enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 974cf8bdc056..9c30d292547d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1794,9 +1794,11 @@ * GEN9 clock gating regs */ #define GEN9_CLKGATE_DIS_0 _MMIO(0x46530) -#define DARBF_GATING_DIS (1 << 27) -#define PWM2_GATING_DIS (1 << 14) -#define PWM1_GATING_DIS (1 << 13) +#define DARBF_GATING_DIS REG_BIT(27) +#define MTL_PIPEDMC_GATING_DIS_A REG_BIT(15) +#define MTL_PIPEDMC_GATING_DIS_B REG_BIT(14) +#define PWM2_GATING_DIS REG_BIT(14) +#define PWM1_GATING_DIS REG_BIT(13) #define GEN9_CLKGATE_DIS_3 _MMIO(0x46538) #define TGL_VRH_GATING_DIS REG_BIT(31) -- cgit From 2b897eb4f5993a221dcd8e4f29fda3046669ed59 Mon Sep 17 00:00:00 2001 From: Madhumitha Tolakanahalli Pradeep Date: Tue, 7 Mar 2023 16:51:11 -0300 Subject: drm/i915/dmc: Load DMC on MTL Add support to load DMC on MTL. According to the spec and based on tests done on real hardware, 0x7000 is a reasonable size limit that covers each possible payload. v2: - Tighten payload size limit. (Matt, Rodrigo) - Use a better name for the defined payload limit. (Rodrigo) Signed-off-by: Madhumitha Tolakanahalli Pradeep Signed-off-by: Gustavo Sousa Cc: Rodrigo Vivi Cc: Matt Roper Cc: Anusha Srivatsa Reviewed-by: Matt Roper Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20230307195111.90767-1-gustavo.sousa@intel.com --- drivers/gpu/drm/i915/display/intel_dmc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_dmc.c') diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index ae247495d9a2..8a88de67ff0a 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -89,10 +89,13 @@ static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915) __stringify(major) "_" \ __stringify(minor) ".bin" +#define XELPDP_DMC_MAX_FW_SIZE 0x7000 #define DISPLAY_VER13_DMC_MAX_FW_SIZE 0x20000 - #define DISPLAY_VER12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE +#define MTL_DMC_PATH DMC_PATH(mtl) +MODULE_FIRMWARE(MTL_DMC_PATH); + #define DG2_DMC_PATH DMC_LEGACY_PATH(dg2, 2, 08) MODULE_FIRMWARE(DG2_DMC_PATH); @@ -995,7 +998,10 @@ void intel_dmc_init(struct drm_i915_private *i915) INIT_WORK(&dmc->work, dmc_load_work_fn); - if (IS_DG2(i915)) { + if (IS_METEORLAKE(i915)) { + dmc->fw_path = MTL_DMC_PATH; + dmc->max_fw_size = XELPDP_DMC_MAX_FW_SIZE; + } else if (IS_DG2(i915)) { dmc->fw_path = DG2_DMC_PATH; dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; } else if (IS_ALDERLAKE_P(i915)) { -- cgit