Lines Matching full:dmc

36  * DOC: DMC Firmware Support
38 * From gen9 onwards we have newly added DMC (Display microcontroller) in display
75 return display->dmc.dmc; in display_to_dmc()
101 * New DMC additions should not use this. This is used solely to remain
102 * compatible with systems that have not yet updated DMC blobs to use
238 /* 0x09 for DMC */
241 /* Includes the DMC specific header in dwords */
256 /* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
298 /* DMC container header length in dwords */
314 /* DMC binary header length */
354 /* DMC RAM start MMIO address */
387 struct intel_dmc *dmc = display_to_dmc(display); in has_dmc_id_fw() local
389 return dmc && dmc->dmc_info[dmc_id].payload; in has_dmc_id_fw()
543 /* keep all pipe DMC events disabled by default */ in disable_dmc_evt()
547 /* also disable the flip queue event on the main DMC on TGL */ in disable_dmc_evt()
552 /* also disable the HRR event on the main DMC on TGL/ADLS */ in disable_dmc_evt()
561 struct intel_dmc *dmc, in dmc_mmiodata() argument
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()
579 * DMC firmware is read from a .bin file and kept in internal memory one time.
587 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_load_program() local
603 for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { 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()
645 struct intel_dmc *dmc = display_to_dmc(display); in assert_dmc_loaded() local
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()
650 "DMC program storage start is NULL\n"); in assert_dmc_loaded()
652 "DMC SSP Base Not fine\n"); in assert_dmc_loaded()
654 "DMC HTP Not fine\n"); in assert_dmc_loaded()
678 static void dmc_set_fw_offset(struct intel_dmc *dmc, in dmc_set_fw_offset() argument
684 struct intel_display *display = dmc->display; 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()
710 static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, in dmc_mmio_addr_sanity_check() argument
714 struct intel_display *display = dmc->display; in dmc_mmio_addr_sanity_check()
743 static u32 parse_dmc_fw_header(struct intel_dmc *dmc, in parse_dmc_fw_header() argument
747 struct intel_display *display = dmc->display; in parse_dmc_fw_header()
748 struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id]; in parse_dmc_fw_header()
795 drm_err(display->drm, "Unknown DMC fw header version: %u\n", in parse_dmc_fw_header()
801 drm_err(display->drm, "DMC firmware has wrong dmc header length " in parse_dmc_fw_header()
806 /* Cache the dmc header info. */ 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()
812 if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, 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()
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()
856 drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_header()
861 parse_dmc_fw_package(struct intel_dmc *dmc, in parse_dmc_fw_package() argument
866 struct intel_display *display = dmc->display; in parse_dmc_fw_package()
879 drm_err(display->drm, "DMC firmware has unknown header version %u\n", in parse_dmc_fw_package()
893 drm_err(display->drm, "DMC firmware has wrong package header length " in parse_dmc_fw_package()
904 dmc_set_fw_offset(dmc, fw_info, num_entries, si, in parse_dmc_fw_package()
911 drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_package()
916 static u32 parse_dmc_fw_css(struct intel_dmc *dmc, in parse_dmc_fw_css() argument
920 struct intel_display *display = dmc->display; in parse_dmc_fw_css()
923 drm_err(display->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_css()
929 drm_err(display->drm, "DMC firmware has wrong CSS header length " in parse_dmc_fw_css()
935 dmc->version = css_header->version; in parse_dmc_fw_css()
940 static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) in parse_dmc_fw() argument
942 struct intel_display *display = dmc->display; in parse_dmc_fw()
957 r = parse_dmc_fw_css(dmc, css_header, fw->size); in parse_dmc_fw()
965 r = parse_dmc_fw_package(dmc, package_header, si, fw->size - readcount); 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()
982 parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, dmc_id); in parse_dmc_fw()
986 drm_err(display->drm, "DMC firmware main program not found\n"); in parse_dmc_fw()
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()
1005 fetch_and_zero(&display->dmc.wakeref); in intel_dmc_runtime_pm_put()
1022 struct intel_dmc *dmc = container_of(work, typeof(*dmc), work); in dmc_load_work_fn() local
1023 struct intel_display *display = dmc->display; in dmc_load_work_fn()
1028 err = request_firmware(&fw, dmc->fw_path, display->drm->dev); in dmc_load_work_fn()
1034 dmc->fw_path, fallback_path); in dmc_load_work_fn()
1037 dmc->fw_path = fallback_path; in dmc_load_work_fn()
1043 "Failed to load DMC firmware %s (%pe). Disabling runtime power management.\n", 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()
1050 err = parse_dmc_fw(dmc, fw); in dmc_load_work_fn()
1053 "Failed to parse DMC firmware %s (%pe). Disabling runtime power management.\n", in dmc_load_work_fn()
1054 dmc->fw_path, ERR_PTR(err)); 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()
1079 struct intel_dmc *dmc; in intel_dmc_init() local
1085 * Obtain a runtime pm reference, until DMC is loaded, to avoid entering in intel_dmc_init()
1089 * suspend as runtime suspend *requires* a working DMC for whatever in intel_dmc_init()
1094 dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); in intel_dmc_init()
1095 if (!dmc) 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()
1105 drm_info(display->drm, "Disabling DMC firmware and runtime PM\n"); 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()
1114 "No known DMC firmware for platform, disabling runtime PM\n"); 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()
1126 kfree(dmc); in intel_dmc_init()
1130 * intel_dmc_suspend() - prepare DMC firmware before system suspend
1133 * Prepare the DMC firmware before entering system suspend. This includes
1139 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_suspend() local
1144 if (dmc) in intel_dmc_suspend()
1145 flush_work(&dmc->work); in intel_dmc_suspend()
1147 /* Drop the reference held in case DMC isn't loaded. */ in intel_dmc_suspend()
1153 * intel_dmc_resume() - init DMC firmware during system resume
1156 * Reinitialize the DMC firmware during system resume, reacquiring any
1165 * Reacquire the reference to keep RPM disabled in case DMC isn't in intel_dmc_resume()
1173 * intel_dmc_fini() - unload the DMC firmware.
1181 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_fini() local
1188 drm_WARN_ON(display->drm, display->dmc.wakeref); in intel_dmc_fini()
1190 if (dmc) { in intel_dmc_fini()
1192 kfree(dmc->dmc_info[dmc_id].payload); in intel_dmc_fini()
1194 kfree(dmc); in intel_dmc_fini()
1195 display->dmc.dmc = NULL; in intel_dmc_fini()
1207 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_snapshot_capture() local
1217 snapshot->initialized = dmc; in intel_dmc_snapshot_capture()
1219 if (dmc) 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()
1233 drm_printf(p, "DMC fw version: %d.%d\n", in intel_dmc_snapshot_print()
1242 struct intel_dmc *dmc = display_to_dmc(display); in intel_dmc_debugfs_status_show() local
1251 seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); 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()
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()
1298 intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0))); in intel_dmc_debugfs_status_show()