Lines Matching +full:a +full:- +full:display

4  * Permission is hereby granted, free of charge, to any person obtaining a
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
38 * From gen9 onwards we have newly added DMC (Display microcontroller) in display
39 * engine to save and restore the state of display engine when it enter into
40 * low-power state and comes back to normal.
43 #define INTEL_DMC_FIRMWARE_URL "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firm…
55 struct intel_display *display; member
73 static struct intel_dmc *display_to_dmc(struct intel_display *display) in display_to_dmc() argument
75 return display->dmc.dmc; in display_to_dmc()
78 static const char *dmc_firmware_param(struct intel_display *display) in dmc_firmware_param() argument
80 const char *p = display->params.dmc_firmware_path; in dmc_firmware_param()
85 static bool dmc_firmware_param_disabled(struct intel_display *display) in dmc_firmware_param_disabled() argument
87 const char *p = dmc_firmware_param(display); in dmc_firmware_param_disabled()
168 static const char *dmc_firmware_default(struct intel_display *display, u32 *size) in dmc_firmware_default() argument
170 struct drm_i915_private *i915 = to_i915(display->drm); in dmc_firmware_default()
174 if (DISPLAY_VERx100(display) == 3000) { in dmc_firmware_default()
177 } else if (DISPLAY_VERx100(display) == 2000) { in dmc_firmware_default()
180 } else if (DISPLAY_VERx100(display) == 1401) { in dmc_firmware_default()
183 } else if (DISPLAY_VERx100(display) == 1400) { in dmc_firmware_default()
204 } else if (DISPLAY_VER(display) == 11) { in dmc_firmware_default()
235 #define PIPE_TO_DMC_ID(pipe) (DMC_FW_PIPEA + ((pipe) - PIPE_A))
287 /* Stepping (A, B, C, ..., *). * is a wildcard */
290 /* Sub-stepping (0, 1, ..., *). * is a wildcard */
385 static bool has_dmc_id_fw(struct intel_display *display, enum intel_dmc_id dmc_id) in has_dmc_id_fw() argument
387 struct intel_dmc *dmc = display_to_dmc(display); in has_dmc_id_fw()
389 return dmc && dmc->dmc_info[dmc_id].payload; in has_dmc_id_fw()
392 bool intel_dmc_has_payload(struct intel_display *display) in intel_dmc_has_payload() argument
394 return has_dmc_id_fw(display, DMC_FW_MAIN); in intel_dmc_has_payload()
398 intel_get_stepping_info(struct intel_display *display, in intel_get_stepping_info() argument
401 const char *step_name = intel_step_name(INTEL_DISPLAY_STEP(display)); in intel_get_stepping_info()
403 si->stepping = step_name[0]; in intel_get_stepping_info()
404 si->substepping = step_name[1]; in intel_get_stepping_info()
408 static void gen9_set_dc_state_debugmask(struct intel_display *display) in gen9_set_dc_state_debugmask() argument
411 intel_de_rmw(display, DC_STATE_DEBUG, 0, in gen9_set_dc_state_debugmask()
413 intel_de_posting_read(display, DC_STATE_DEBUG); in gen9_set_dc_state_debugmask()
416 static void disable_event_handler(struct intel_display *display, in disable_event_handler() argument
419 intel_de_write(display, ctl_reg, in disable_event_handler()
424 intel_de_write(display, htp_reg, 0); in disable_event_handler()
427 static void disable_all_event_handlers(struct intel_display *display) in disable_all_event_handlers() argument
431 /* TODO: disable the event handlers on pre-GEN12 platforms as well */ in disable_all_event_handlers()
432 if (DISPLAY_VER(display) < 12) in disable_all_event_handlers()
438 if (!has_dmc_id_fw(display, dmc_id)) in disable_all_event_handlers()
442 disable_event_handler(display, in disable_all_event_handlers()
443 DMC_EVT_CTL(display, dmc_id, handler), in disable_all_event_handlers()
444 DMC_EVT_HTP(display, dmc_id, handler)); in disable_all_event_handlers()
448 static void adlp_pipedmc_clock_gating_wa(struct intel_display *display, bool enable) in adlp_pipedmc_clock_gating_wa() argument
453 * Wa_16015201720:adl-p,dg2 in adlp_pipedmc_clock_gating_wa()
455 * for pipe A and B. in adlp_pipedmc_clock_gating_wa()
461 intel_de_rmw(display, CLKGATE_DIS_PSL_EXT(pipe), in adlp_pipedmc_clock_gating_wa()
465 intel_de_rmw(display, CLKGATE_DIS_PSL_EXT(pipe), in adlp_pipedmc_clock_gating_wa()
469 static void mtl_pipedmc_clock_gating_wa(struct intel_display *display) in mtl_pipedmc_clock_gating_wa() argument
474 * for pipe A and B. in mtl_pipedmc_clock_gating_wa()
476 intel_de_rmw(display, GEN9_CLKGATE_DIS_0, 0, in mtl_pipedmc_clock_gating_wa()
480 static void pipedmc_clock_gating_wa(struct intel_display *display, bool enable) in pipedmc_clock_gating_wa() argument
482 if (DISPLAY_VER(display) >= 14 && enable) in pipedmc_clock_gating_wa()
483 mtl_pipedmc_clock_gating_wa(display); in pipedmc_clock_gating_wa()
484 else if (DISPLAY_VER(display) == 13) in pipedmc_clock_gating_wa()
485 adlp_pipedmc_clock_gating_wa(display, enable); in pipedmc_clock_gating_wa()
488 void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe) in intel_dmc_enable_pipe() argument
492 if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) in intel_dmc_enable_pipe()
495 if (DISPLAY_VER(display) >= 14) in intel_dmc_enable_pipe()
496 intel_de_rmw(display, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe)); in intel_dmc_enable_pipe()
498 intel_de_rmw(display, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE); in intel_dmc_enable_pipe()
501 void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe) in intel_dmc_disable_pipe() argument
505 if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) in intel_dmc_disable_pipe()
508 if (DISPLAY_VER(display) >= 14) in intel_dmc_disable_pipe()
509 intel_de_rmw(display, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0); in intel_dmc_disable_pipe()
511 intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); in intel_dmc_disable_pipe()
514 static bool is_dmc_evt_ctl_reg(struct intel_display *display, in is_dmc_evt_ctl_reg() argument
518 u32 start = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0)); in is_dmc_evt_ctl_reg()
519 u32 end = i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); in is_dmc_evt_ctl_reg()
524 static bool is_dmc_evt_htp_reg(struct intel_display *display, in is_dmc_evt_htp_reg() argument
528 u32 start = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0)); in is_dmc_evt_htp_reg()
529 u32 end = i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, DMC_EVENT_HANDLER_COUNT_GEN12)); in is_dmc_evt_htp_reg()
534 static bool disable_dmc_evt(struct intel_display *display, in disable_dmc_evt() argument
538 struct drm_i915_private *i915 = to_i915(display->drm); in disable_dmc_evt()
540 if (!is_dmc_evt_ctl_reg(display, dmc_id, reg)) in disable_dmc_evt()
560 static u32 dmc_mmiodata(struct intel_display *display, in dmc_mmiodata() argument
564 if (disable_dmc_evt(display, dmc_id, in dmc_mmiodata()
565 dmc->dmc_info[dmc_id].mmioaddr[i], in dmc_mmiodata()
566 dmc->dmc_info[dmc_id].mmiodata[i])) in dmc_mmiodata()
572 return dmc->dmc_info[dmc_id].mmiodata[i]; in dmc_mmiodata()
576 * intel_dmc_load_program() - write the firmware from memory to register.
577 * @display: display instance
579 * DMC firmware is read from a .bin file and kept in internal memory one time.
580 * Everytime display comes back from low power state this function is called to
583 void intel_dmc_load_program(struct intel_display *display) in intel_dmc_load_program() argument
585 struct drm_i915_private *i915 __maybe_unused = to_i915(display->drm); in intel_dmc_load_program()
586 struct i915_power_domains *power_domains = &display->power.domains; in intel_dmc_load_program()
587 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_load_program()
591 if (!intel_dmc_has_payload(display)) in intel_dmc_load_program()
594 pipedmc_clock_gating_wa(display, true); in intel_dmc_load_program()
596 disable_all_event_handlers(display); in intel_dmc_load_program()
598 assert_rpm_wakelock_held(&i915->runtime_pm); in intel_dmc_load_program()
603 for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { in intel_dmc_load_program()
604 intel_de_write_fw(display, in intel_dmc_load_program()
605 DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), in intel_dmc_load_program()
606 dmc->dmc_info[dmc_id].payload[i]); in intel_dmc_load_program()
613 for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { in intel_dmc_load_program()
614 intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i], in intel_dmc_load_program()
615 dmc_mmiodata(display, dmc, dmc_id, i)); in intel_dmc_load_program()
619 power_domains->dc_state = 0; in intel_dmc_load_program()
621 gen9_set_dc_state_debugmask(display); in intel_dmc_load_program()
623 pipedmc_clock_gating_wa(display, false); in intel_dmc_load_program()
627 * intel_dmc_disable_program() - disable the firmware
628 * @display: display instance
631 * inactive after the display is uninitialized.
633 void intel_dmc_disable_program(struct intel_display *display) in intel_dmc_disable_program() argument
635 if (!intel_dmc_has_payload(display)) in intel_dmc_disable_program()
638 pipedmc_clock_gating_wa(display, true); in intel_dmc_disable_program()
639 disable_all_event_handlers(display); in intel_dmc_disable_program()
640 pipedmc_clock_gating_wa(display, false); in intel_dmc_disable_program()
643 void assert_dmc_loaded(struct intel_display *display) in assert_dmc_loaded() argument
645 struct intel_dmc *dmc = display_to_dmc(display); in assert_dmc_loaded()
647 drm_WARN_ONCE(display->drm, !dmc, "DMC not initialized\n"); in assert_dmc_loaded()
648 drm_WARN_ONCE(display->drm, dmc && in assert_dmc_loaded()
649 !intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), in assert_dmc_loaded()
651 drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_SSP_BASE), in assert_dmc_loaded()
653 drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_HTP_SKL), in assert_dmc_loaded()
660 if ((fw_info->substepping == '*' && si->stepping == fw_info->stepping) || in fw_info_matches_stepping()
661 (si->stepping == fw_info->stepping && si->substepping == fw_info->substepping) || in fw_info_matches_stepping()
663 * If we don't find a more specific one from above two checks, we in fw_info_matches_stepping()
667 (si->stepping == '*' && si->substepping == fw_info->substepping) || in fw_info_matches_stepping()
668 (fw_info->stepping == '*' && fw_info->substepping == '*')) in fw_info_matches_stepping()
684 struct intel_display *display = dmc->display; in dmc_set_fw_offset() local
692 drm_dbg(display->drm, "Unsupported firmware id: %u\n", dmc_id); in dmc_set_fw_offset()
697 * check for the stepping since we already found a previous FW in dmc_set_fw_offset()
700 if (dmc->dmc_info[dmc_id].present) in dmc_set_fw_offset()
704 dmc->dmc_info[dmc_id].present = true; in dmc_set_fw_offset()
705 dmc->dmc_info[dmc_id].dmc_offset = fw_info[i].offset; in dmc_set_fw_offset()
714 struct intel_display *display = dmc->display; in dmc_mmio_addr_sanity_check() local
724 } else if (DISPLAY_VER(display) >= 13) { in dmc_mmio_addr_sanity_check()
727 } else if (DISPLAY_VER(display) >= 12) { in dmc_mmio_addr_sanity_check()
731 drm_warn(display->drm, "Unknown mmio range for sanity check"); in dmc_mmio_addr_sanity_check()
747 struct intel_display *display = dmc->display; in parse_dmc_fw_header() local
748 struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id]; in parse_dmc_fw_header()
754 BUILD_BUG_ON(ARRAY_SIZE(dmc_info->mmioaddr) < DMC_V3_MAX_MMIO_COUNT || in parse_dmc_fw_header()
755 ARRAY_SIZE(dmc_info->mmioaddr) < DMC_V1_MAX_MMIO_COUNT); in parse_dmc_fw_header()
765 if (dmc_header->header_ver == 3) { in parse_dmc_fw_header()
772 mmioaddr = v3->mmioaddr; in parse_dmc_fw_header()
773 mmiodata = v3->mmiodata; in parse_dmc_fw_header()
774 mmio_count = v3->mmio_count; in parse_dmc_fw_header()
777 header_len_bytes = dmc_header->header_len * 4; in parse_dmc_fw_header()
778 start_mmioaddr = v3->start_mmioaddr; in parse_dmc_fw_header()
780 } else if (dmc_header->header_ver == 1) { in parse_dmc_fw_header()
787 mmioaddr = v1->mmioaddr; in parse_dmc_fw_header()
788 mmiodata = v1->mmiodata; in parse_dmc_fw_header()
789 mmio_count = v1->mmio_count; in parse_dmc_fw_header()
791 header_len_bytes = dmc_header->header_len; in parse_dmc_fw_header()
795 drm_err(display->drm, "Unknown DMC fw header version: %u\n", in parse_dmc_fw_header()
796 dmc_header->header_ver); in parse_dmc_fw_header()
801 drm_err(display->drm, "DMC firmware has wrong dmc header length " in parse_dmc_fw_header()
808 drm_err(display->drm, "DMC firmware has wrong mmio count %u\n", mmio_count); in parse_dmc_fw_header()
813 dmc_header->header_ver, dmc_id)) { in parse_dmc_fw_header()
814 drm_err(display->drm, "DMC firmware has Wrong MMIO Addresses\n"); in parse_dmc_fw_header()
818 drm_dbg_kms(display->drm, "DMC %d:\n", dmc_id); in parse_dmc_fw_header()
820 dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]); in parse_dmc_fw_header()
821 dmc_info->mmiodata[i] = mmiodata[i]; in parse_dmc_fw_header()
823 drm_dbg_kms(display->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n", in parse_dmc_fw_header()
825 is_dmc_evt_ctl_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" : in parse_dmc_fw_header()
826 is_dmc_evt_htp_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "", in parse_dmc_fw_header()
827 disable_dmc_evt(display, dmc_id, dmc_info->mmioaddr[i], in parse_dmc_fw_header()
828 dmc_info->mmiodata[i]) ? " (disabling)" : ""); in parse_dmc_fw_header()
830 dmc_info->mmio_count = mmio_count; in parse_dmc_fw_header()
831 dmc_info->start_mmioaddr = start_mmioaddr; in parse_dmc_fw_header()
833 rem_size -= header_len_bytes; in parse_dmc_fw_header()
836 payload_size = dmc_header->fw_size * 4; in parse_dmc_fw_header()
840 if (payload_size > dmc->max_fw_size) { in parse_dmc_fw_header()
841 drm_err(display->drm, "DMC FW too big (%u bytes)\n", payload_size); in parse_dmc_fw_header()
844 dmc_info->dmc_fw_size = dmc_header->fw_size; in parse_dmc_fw_header()
846 dmc_info->payload = kmalloc(payload_size, GFP_KERNEL); in parse_dmc_fw_header()
847 if (!dmc_info->payload) in parse_dmc_fw_header()
851 memcpy(dmc_info->payload, payload, payload_size); in parse_dmc_fw_header()
856 drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_header()
866 struct intel_display *display = dmc->display; in parse_dmc_fw_package() local
874 if (package_header->header_ver == 1) { in parse_dmc_fw_package()
876 } else if (package_header->header_ver == 2) { in parse_dmc_fw_package()
879 drm_err(display->drm, "DMC firmware has unknown header version %u\n", in parse_dmc_fw_package()
880 package_header->header_ver); in parse_dmc_fw_package()
892 if (package_header->header_len * 4 != package_size) { in parse_dmc_fw_package()
893 drm_err(display->drm, "DMC firmware has wrong package header length " in parse_dmc_fw_package()
898 num_entries = package_header->num_entries; in parse_dmc_fw_package()
899 if (WARN_ON(package_header->num_entries > max_entries)) in parse_dmc_fw_package()
905 package_header->header_ver); in parse_dmc_fw_package()
911 drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_package()
920 struct intel_display *display = dmc->display; in parse_dmc_fw_css() local
923 drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_css()
928 (css_header->header_len * 4)) { in parse_dmc_fw_css()
929 drm_err(display->drm, "DMC firmware has wrong CSS header length " in parse_dmc_fw_css()
931 (css_header->header_len * 4)); in parse_dmc_fw_css()
935 dmc->version = css_header->version; in parse_dmc_fw_css()
942 struct intel_display *display = dmc->display; in parse_dmc_fw() local
947 const struct stepping_info *si = intel_get_stepping_info(display, &display_info); in parse_dmc_fw()
953 return -EINVAL; in parse_dmc_fw()
956 css_header = (struct intel_css_header *)fw->data; in parse_dmc_fw()
957 r = parse_dmc_fw_css(dmc, css_header, fw->size); in parse_dmc_fw()
959 return -EINVAL; in parse_dmc_fw()
964 package_header = (struct intel_package_header *)&fw->data[readcount]; in parse_dmc_fw()
965 r = parse_dmc_fw_package(dmc, package_header, si, fw->size - readcount); in parse_dmc_fw()
967 return -EINVAL; in parse_dmc_fw()
972 if (!dmc->dmc_info[dmc_id].present) in parse_dmc_fw()
975 offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4; in parse_dmc_fw()
976 if (offset > fw->size) { in parse_dmc_fw()
977 drm_err(display->drm, "Reading beyond the fw_size\n"); in parse_dmc_fw()
981 dmc_header = (struct intel_dmc_header_base *)&fw->data[offset]; in parse_dmc_fw()
982 parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, dmc_id); in parse_dmc_fw()
985 if (!intel_dmc_has_payload(display)) { in parse_dmc_fw()
986 drm_err(display->drm, "DMC firmware main program not found\n"); in parse_dmc_fw()
987 return -ENOENT; in parse_dmc_fw()
993 static void intel_dmc_runtime_pm_get(struct intel_display *display) in intel_dmc_runtime_pm_get() argument
995 struct drm_i915_private *i915 = to_i915(display->drm); in intel_dmc_runtime_pm_get()
997 drm_WARN_ON(display->drm, display->dmc.wakeref); in intel_dmc_runtime_pm_get()
998 display->dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); in intel_dmc_runtime_pm_get()
1001 static void intel_dmc_runtime_pm_put(struct intel_display *display) in intel_dmc_runtime_pm_put() argument
1003 struct drm_i915_private *i915 = to_i915(display->drm); in intel_dmc_runtime_pm_put()
1005 fetch_and_zero(&display->dmc.wakeref); in intel_dmc_runtime_pm_put()
1010 static const char *dmc_fallback_path(struct intel_display *display) in dmc_fallback_path() argument
1012 struct drm_i915_private *i915 = to_i915(display->drm); in dmc_fallback_path()
1023 struct intel_display *display = dmc->display; in dmc_load_work_fn() local
1028 err = request_firmware(&fw, dmc->fw_path, display->drm->dev); in dmc_load_work_fn()
1030 if (err == -ENOENT && !dmc_firmware_param(display)) { in dmc_load_work_fn()
1031 fallback_path = dmc_fallback_path(display); in dmc_load_work_fn()
1033 drm_dbg_kms(display->drm, "%s not found, falling back to %s\n", in dmc_load_work_fn()
1034 dmc->fw_path, fallback_path); in dmc_load_work_fn()
1035 err = request_firmware(&fw, fallback_path, display->drm->dev); in dmc_load_work_fn()
1037 dmc->fw_path = fallback_path; in dmc_load_work_fn()
1042 drm_notice(display->drm, in dmc_load_work_fn()
1044 dmc->fw_path, ERR_PTR(err)); in dmc_load_work_fn()
1045 drm_notice(display->drm, "DMC firmware homepage: %s", in dmc_load_work_fn()
1052 drm_notice(display->drm, in dmc_load_work_fn()
1054 dmc->fw_path, ERR_PTR(err)); in dmc_load_work_fn()
1058 intel_dmc_load_program(display); in dmc_load_work_fn()
1059 intel_dmc_runtime_pm_put(display); in dmc_load_work_fn()
1061 drm_info(display->drm, "Finished loading DMC firmware %s (v%u.%u)\n", in dmc_load_work_fn()
1062 dmc->fw_path, DMC_VERSION_MAJOR(dmc->version), in dmc_load_work_fn()
1063 DMC_VERSION_MINOR(dmc->version)); in dmc_load_work_fn()
1070 * intel_dmc_init() - initialize the firmware loading.
1071 * @display: display instance
1073 * This function is called at the time of loading the display driver to read
1074 * firmware from a .bin file and copied into a internal memory.
1076 void intel_dmc_init(struct intel_display *display) in intel_dmc_init() argument
1078 struct drm_i915_private *i915 = to_i915(display->drm); in intel_dmc_init()
1081 if (!HAS_DMC(display)) in intel_dmc_init()
1085 * Obtain a runtime pm reference, until DMC is loaded, to avoid entering in intel_dmc_init()
1086 * runtime-suspend. in intel_dmc_init()
1089 * suspend as runtime suspend *requires* a working DMC for whatever in intel_dmc_init()
1092 intel_dmc_runtime_pm_get(display); in intel_dmc_init()
1098 dmc->display = display; in intel_dmc_init()
1100 INIT_WORK(&dmc->work, dmc_load_work_fn); in intel_dmc_init()
1102 dmc->fw_path = dmc_firmware_default(display, &dmc->max_fw_size); in intel_dmc_init()
1104 if (dmc_firmware_param_disabled(display)) { in intel_dmc_init()
1105 drm_info(display->drm, "Disabling DMC firmware and runtime PM\n"); in intel_dmc_init()
1109 if (dmc_firmware_param(display)) in intel_dmc_init()
1110 dmc->fw_path = dmc_firmware_param(display); in intel_dmc_init()
1112 if (!dmc->fw_path) { in intel_dmc_init()
1113 drm_dbg_kms(display->drm, in intel_dmc_init()
1118 display->dmc.dmc = dmc; in intel_dmc_init()
1120 drm_dbg_kms(display->drm, "Loading %s\n", dmc->fw_path); in intel_dmc_init()
1121 queue_work(i915->unordered_wq, &dmc->work); in intel_dmc_init()
1130 * intel_dmc_suspend() - prepare DMC firmware before system suspend
1131 * @display: display instance
1137 void intel_dmc_suspend(struct intel_display *display) in intel_dmc_suspend() argument
1139 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_suspend()
1141 if (!HAS_DMC(display)) in intel_dmc_suspend()
1145 flush_work(&dmc->work); in intel_dmc_suspend()
1148 if (!intel_dmc_has_payload(display)) in intel_dmc_suspend()
1149 intel_dmc_runtime_pm_put(display); in intel_dmc_suspend()
1153 * intel_dmc_resume() - init DMC firmware during system resume
1154 * @display: display instance
1159 void intel_dmc_resume(struct intel_display *display) in intel_dmc_resume() argument
1161 if (!HAS_DMC(display)) in intel_dmc_resume()
1168 if (!intel_dmc_has_payload(display)) in intel_dmc_resume()
1169 intel_dmc_runtime_pm_get(display); in intel_dmc_resume()
1173 * intel_dmc_fini() - unload the DMC firmware.
1174 * @display: display instance
1179 void intel_dmc_fini(struct intel_display *display) in intel_dmc_fini() argument
1181 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_fini()
1184 if (!HAS_DMC(display)) in intel_dmc_fini()
1187 intel_dmc_suspend(display); in intel_dmc_fini()
1188 drm_WARN_ON(display->drm, display->dmc.wakeref); in intel_dmc_fini()
1192 kfree(dmc->dmc_info[dmc_id].payload); in intel_dmc_fini()
1195 display->dmc.dmc = NULL; in intel_dmc_fini()
1205 struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display) in intel_dmc_snapshot_capture() argument
1207 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_snapshot_capture()
1210 if (!HAS_DMC(display)) in intel_dmc_snapshot_capture()
1217 snapshot->initialized = dmc; in intel_dmc_snapshot_capture()
1218 snapshot->loaded = intel_dmc_has_payload(display); in intel_dmc_snapshot_capture()
1220 snapshot->version = dmc->version; in intel_dmc_snapshot_capture()
1230 drm_printf(p, "DMC initialized: %s\n", str_yes_no(snapshot->initialized)); in intel_dmc_snapshot_print()
1231 drm_printf(p, "DMC loaded: %s\n", str_yes_no(snapshot->loaded)); in intel_dmc_snapshot_print()
1232 if (snapshot->initialized) in intel_dmc_snapshot_print()
1234 DMC_VERSION_MAJOR(snapshot->version), in intel_dmc_snapshot_print()
1235 DMC_VERSION_MINOR(snapshot->version)); in intel_dmc_snapshot_print()
1240 struct intel_display *display = m->private; in intel_dmc_debugfs_status_show() local
1241 struct drm_i915_private *i915 = to_i915(display->drm); in intel_dmc_debugfs_status_show()
1242 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_debugfs_status_show()
1246 if (!HAS_DMC(display)) in intel_dmc_debugfs_status_show()
1247 return -ENODEV; in intel_dmc_debugfs_status_show()
1249 wakeref = intel_runtime_pm_get(&i915->runtime_pm); in intel_dmc_debugfs_status_show()
1253 str_yes_no(intel_dmc_has_payload(display))); in intel_dmc_debugfs_status_show()
1254 seq_printf(m, "path: %s\n", dmc ? dmc->fw_path : "N/A"); in intel_dmc_debugfs_status_show()
1255 seq_printf(m, "Pipe A fw needed: %s\n", in intel_dmc_debugfs_status_show()
1256 str_yes_no(DISPLAY_VER(display) >= 12)); in intel_dmc_debugfs_status_show()
1257 seq_printf(m, "Pipe A fw loaded: %s\n", in intel_dmc_debugfs_status_show()
1258 str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEA))); in intel_dmc_debugfs_status_show()
1261 DISPLAY_VER(display) >= 14)); in intel_dmc_debugfs_status_show()
1263 str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEB))); in intel_dmc_debugfs_status_show()
1265 if (!intel_dmc_has_payload(display)) in intel_dmc_debugfs_status_show()
1268 seq_printf(m, "version: %d.%d\n", DMC_VERSION_MAJOR(dmc->version), in intel_dmc_debugfs_status_show()
1269 DMC_VERSION_MINOR(dmc->version)); in intel_dmc_debugfs_status_show()
1271 if (DISPLAY_VER(display) >= 12) { in intel_dmc_debugfs_status_show()
1274 if (IS_DGFX(i915) || DISPLAY_VER(display) >= 14) { in intel_dmc_debugfs_status_show()
1284 intel_de_read(display, dc3co_reg)); in intel_dmc_debugfs_status_show()
1292 seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(display, dc5_reg)); in intel_dmc_debugfs_status_show()
1294 seq_printf(m, "DC5 -> DC6 count: %d\n", in intel_dmc_debugfs_status_show()
1295 intel_de_read(display, dc6_reg)); in intel_dmc_debugfs_status_show()
1298 intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0))); in intel_dmc_debugfs_status_show()
1302 intel_de_read(display, DMC_SSP_BASE)); in intel_dmc_debugfs_status_show()
1303 seq_printf(m, "htp: 0x%08x\n", intel_de_read(display, DMC_HTP_SKL)); in intel_dmc_debugfs_status_show()
1305 intel_runtime_pm_put(&i915->runtime_pm, wakeref); in intel_dmc_debugfs_status_show()
1312 void intel_dmc_debugfs_register(struct intel_display *display) in intel_dmc_debugfs_register() argument
1314 struct drm_minor *minor = display->drm->primary; in intel_dmc_debugfs_register()
1316 debugfs_create_file("i915_dmc_info", 0444, minor->debugfs_root, in intel_dmc_debugfs_register()
1317 display, &intel_dmc_debugfs_status_fops); in intel_dmc_debugfs_register()