Lines Matching full:dmc
34 * DOC: DMC Firmware Support
36 * From gen9 onwards we have newly added DMC (Display microcontroller) in display
71 return i915->display.dmc.dmc; in i915_to_dmc()
82 * New DMC additions should not use this. This is used solely to remain
83 * compatible with systems that have not yet updated DMC blobs to use
149 /* 0x09 for DMC */
152 /* Includes the DMC specific header in dwords */
167 /* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
209 /* DMC container header length in dwords */
225 /* DMC binary header length */
265 /* DMC RAM start MMIO address */
298 struct intel_dmc *dmc = i915_to_dmc(i915); in has_dmc_id_fw() local
300 return dmc && dmc->dmc_info[dmc_id].payload; in has_dmc_id_fw()
452 /* keep all pipe DMC events disabled by default */ in disable_dmc_evt()
456 /* also disable the flip queue event on the main DMC on TGL */ in disable_dmc_evt()
461 /* also disable the HRR event on the main DMC on TGL/ADLS */ in disable_dmc_evt()
470 struct intel_dmc *dmc, in dmc_mmiodata() argument
474 dmc->dmc_info[dmc_id].mmioaddr[i], in dmc_mmiodata()
475 dmc->dmc_info[dmc_id].mmiodata[i])) in dmc_mmiodata()
481 return dmc->dmc_info[dmc_id].mmiodata[i]; in dmc_mmiodata()
488 * DMC firmware is read from a .bin file and kept in internal memory one time.
495 struct intel_dmc *dmc = i915_to_dmc(i915); in intel_dmc_load_program() local
511 for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { in intel_dmc_load_program()
513 DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), in intel_dmc_load_program()
514 dmc->dmc_info[dmc_id].payload[i]); in intel_dmc_load_program()
521 for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { in intel_dmc_load_program()
522 intel_de_write(i915, dmc->dmc_info[dmc_id].mmioaddr[i], in intel_dmc_load_program()
523 dmc_mmiodata(i915, dmc, dmc_id, i)); in intel_dmc_load_program()
553 struct intel_dmc *dmc = i915_to_dmc(i915); in assert_dmc_loaded() local
555 drm_WARN_ONCE(&i915->drm, !dmc, "DMC not initialized\n"); in assert_dmc_loaded()
556 drm_WARN_ONCE(&i915->drm, dmc && in assert_dmc_loaded()
557 !intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), in assert_dmc_loaded()
558 "DMC program storage start is NULL\n"); in assert_dmc_loaded()
560 "DMC SSP Base Not fine\n"); in assert_dmc_loaded()
562 "DMC HTP Not fine\n"); in assert_dmc_loaded()
586 static void dmc_set_fw_offset(struct intel_dmc *dmc, in dmc_set_fw_offset() argument
592 struct drm_i915_private *i915 = dmc->i915; in dmc_set_fw_offset()
608 if (dmc->dmc_info[dmc_id].present) in dmc_set_fw_offset()
612 dmc->dmc_info[dmc_id].present = true; in dmc_set_fw_offset()
613 dmc->dmc_info[dmc_id].dmc_offset = fw_info[i].offset; in dmc_set_fw_offset()
618 static bool dmc_mmio_addr_sanity_check(struct intel_dmc *dmc, in dmc_mmio_addr_sanity_check() argument
622 struct drm_i915_private *i915 = dmc->i915; in dmc_mmio_addr_sanity_check()
651 static u32 parse_dmc_fw_header(struct intel_dmc *dmc, in parse_dmc_fw_header() argument
655 struct drm_i915_private *i915 = dmc->i915; in parse_dmc_fw_header()
656 struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id]; in parse_dmc_fw_header()
703 drm_err(&i915->drm, "Unknown DMC fw header version: %u\n", in parse_dmc_fw_header()
709 drm_err(&i915->drm, "DMC firmware has wrong dmc header length " in parse_dmc_fw_header()
714 /* Cache the dmc header info. */ in parse_dmc_fw_header()
716 drm_err(&i915->drm, "DMC firmware has wrong mmio count %u\n", mmio_count); in parse_dmc_fw_header()
720 if (!dmc_mmio_addr_sanity_check(dmc, mmioaddr, mmio_count, in parse_dmc_fw_header()
722 drm_err(&i915->drm, "DMC firmware has Wrong MMIO Addresses\n"); in parse_dmc_fw_header()
726 drm_dbg_kms(&i915->drm, "DMC %d:\n", dmc_id); in parse_dmc_fw_header()
748 if (payload_size > dmc->max_fw_size) { in parse_dmc_fw_header()
749 drm_err(&i915->drm, "DMC FW too big (%u bytes)\n", payload_size); in parse_dmc_fw_header()
764 drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_header()
769 parse_dmc_fw_package(struct intel_dmc *dmc, in parse_dmc_fw_package() argument
774 struct drm_i915_private *i915 = dmc->i915; in parse_dmc_fw_package()
787 drm_err(&i915->drm, "DMC firmware has unknown header version %u\n", in parse_dmc_fw_package()
801 drm_err(&i915->drm, "DMC firmware has wrong package header length " in parse_dmc_fw_package()
812 dmc_set_fw_offset(dmc, fw_info, num_entries, si, in parse_dmc_fw_package()
819 drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_package()
824 static u32 parse_dmc_fw_css(struct intel_dmc *dmc, in parse_dmc_fw_css() argument
828 struct drm_i915_private *i915 = dmc->i915; in parse_dmc_fw_css()
831 drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n"); in parse_dmc_fw_css()
837 drm_err(&i915->drm, "DMC firmware has wrong CSS header length " in parse_dmc_fw_css()
843 dmc->version = css_header->version; in parse_dmc_fw_css()
848 static void parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw) in parse_dmc_fw() argument
850 struct drm_i915_private *i915 = dmc->i915; in parse_dmc_fw()
865 r = parse_dmc_fw_css(dmc, css_header, fw->size); in parse_dmc_fw()
873 r = parse_dmc_fw_package(dmc, package_header, si, fw->size - readcount); in parse_dmc_fw()
880 if (!dmc->dmc_info[dmc_id].present) in parse_dmc_fw()
883 offset = readcount + dmc->dmc_info[dmc_id].dmc_offset * 4; in parse_dmc_fw()
890 parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, dmc_id); in parse_dmc_fw()
896 drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref); in intel_dmc_runtime_pm_get()
897 i915->display.dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT); in intel_dmc_runtime_pm_get()
903 fetch_and_zero(&i915->display.dmc.wakeref); in intel_dmc_runtime_pm_put()
918 struct intel_dmc *dmc = container_of(work, typeof(*dmc), work); in dmc_load_work_fn() local
919 struct drm_i915_private *i915 = dmc->i915; in dmc_load_work_fn()
924 err = request_firmware(&fw, dmc->fw_path, i915->drm.dev); in dmc_load_work_fn()
930 dmc->fw_path, fallback_path); in dmc_load_work_fn()
933 dmc->fw_path = fallback_path; in dmc_load_work_fn()
937 parse_dmc_fw(dmc, fw); in dmc_load_work_fn()
943 drm_info(&i915->drm, "Finished loading DMC firmware %s (v%u.%u)\n", in dmc_load_work_fn()
944 dmc->fw_path, DMC_VERSION_MAJOR(dmc->version), in dmc_load_work_fn()
945 DMC_VERSION_MINOR(dmc->version)); in dmc_load_work_fn()
948 "Failed to load DMC firmware %s." in dmc_load_work_fn()
950 dmc->fw_path); in dmc_load_work_fn()
951 drm_notice(&i915->drm, "DMC firmware homepage: %s", in dmc_load_work_fn()
967 struct intel_dmc *dmc; in intel_dmc_init() local
973 * Obtain a runtime pm reference, until DMC is loaded, to avoid entering in intel_dmc_init()
977 * suspend as runtime suspend *requires* a working DMC for whatever in intel_dmc_init()
982 dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); in intel_dmc_init()
983 if (!dmc) in intel_dmc_init()
986 dmc->i915 = i915; in intel_dmc_init()
988 INIT_WORK(&dmc->work, dmc_load_work_fn); in intel_dmc_init()
991 dmc->fw_path = MTL_DMC_PATH; in intel_dmc_init()
992 dmc->max_fw_size = XELPDP_DMC_MAX_FW_SIZE; in intel_dmc_init()
994 dmc->fw_path = DG2_DMC_PATH; in intel_dmc_init()
995 dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; in intel_dmc_init()
997 dmc->fw_path = ADLP_DMC_PATH; in intel_dmc_init()
998 dmc->max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; in intel_dmc_init()
1000 dmc->fw_path = ADLS_DMC_PATH; in intel_dmc_init()
1001 dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; in intel_dmc_init()
1003 dmc->fw_path = DG1_DMC_PATH; in intel_dmc_init()
1004 dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; in intel_dmc_init()
1006 dmc->fw_path = RKL_DMC_PATH; in intel_dmc_init()
1007 dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; in intel_dmc_init()
1009 dmc->fw_path = TGL_DMC_PATH; in intel_dmc_init()
1010 dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; in intel_dmc_init()
1012 dmc->fw_path = ICL_DMC_PATH; in intel_dmc_init()
1013 dmc->max_fw_size = ICL_DMC_MAX_FW_SIZE; in intel_dmc_init()
1015 dmc->fw_path = GLK_DMC_PATH; in intel_dmc_init()
1016 dmc->max_fw_size = GLK_DMC_MAX_FW_SIZE; in intel_dmc_init()
1020 dmc->fw_path = KBL_DMC_PATH; in intel_dmc_init()
1021 dmc->max_fw_size = KBL_DMC_MAX_FW_SIZE; in intel_dmc_init()
1023 dmc->fw_path = SKL_DMC_PATH; in intel_dmc_init()
1024 dmc->max_fw_size = SKL_DMC_MAX_FW_SIZE; in intel_dmc_init()
1026 dmc->fw_path = BXT_DMC_PATH; in intel_dmc_init()
1027 dmc->max_fw_size = BXT_DMC_MAX_FW_SIZE; in intel_dmc_init()
1033 "Disabling DMC firmware and runtime PM\n"); in intel_dmc_init()
1037 dmc->fw_path = i915->params.dmc_firmware_path; in intel_dmc_init()
1040 if (!dmc->fw_path) { in intel_dmc_init()
1042 "No known DMC firmware for platform, disabling runtime PM\n"); in intel_dmc_init()
1046 i915->display.dmc.dmc = dmc; in intel_dmc_init()
1048 drm_dbg_kms(&i915->drm, "Loading %s\n", dmc->fw_path); in intel_dmc_init()
1049 queue_work(i915->unordered_wq, &dmc->work); in intel_dmc_init()
1054 kfree(dmc); in intel_dmc_init()
1058 * intel_dmc_suspend() - prepare DMC firmware before system suspend
1061 * Prepare the DMC firmware before entering system suspend. This includes
1067 struct intel_dmc *dmc = i915_to_dmc(i915); in intel_dmc_suspend() local
1072 if (dmc) in intel_dmc_suspend()
1073 flush_work(&dmc->work); in intel_dmc_suspend()
1075 /* Drop the reference held in case DMC isn't loaded. */ in intel_dmc_suspend()
1081 * intel_dmc_resume() - init DMC firmware during system resume
1084 * Reinitialize the DMC firmware during system resume, reacquiring any
1093 * Reacquire the reference to keep RPM disabled in case DMC isn't in intel_dmc_resume()
1101 * intel_dmc_fini() - unload the DMC firmware.
1109 struct intel_dmc *dmc = i915_to_dmc(i915); in intel_dmc_fini() local
1116 drm_WARN_ON(&i915->drm, i915->display.dmc.wakeref); in intel_dmc_fini()
1118 if (dmc) { in intel_dmc_fini()
1120 kfree(dmc->dmc_info[dmc_id].payload); in intel_dmc_fini()
1122 kfree(dmc); in intel_dmc_fini()
1123 i915->display.dmc.dmc = NULL; in intel_dmc_fini()
1130 struct intel_dmc *dmc = i915_to_dmc(i915); in intel_dmc_print_error_state() local
1135 i915_error_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); in intel_dmc_print_error_state()
1136 i915_error_printf(m, "DMC loaded: %s\n", in intel_dmc_print_error_state()
1138 if (dmc) in intel_dmc_print_error_state()
1139 i915_error_printf(m, "DMC fw version: %d.%d\n", in intel_dmc_print_error_state()
1140 DMC_VERSION_MAJOR(dmc->version), in intel_dmc_print_error_state()
1141 DMC_VERSION_MINOR(dmc->version)); in intel_dmc_print_error_state()
1147 struct intel_dmc *dmc = i915_to_dmc(i915); in intel_dmc_debugfs_status_show() local
1156 seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); in intel_dmc_debugfs_status_show()
1159 seq_printf(m, "path: %s\n", dmc ? dmc->fw_path : "N/A"); in intel_dmc_debugfs_status_show()
1173 seq_printf(m, "version: %d.%d\n", DMC_VERSION_MAJOR(dmc->version), in intel_dmc_debugfs_status_show()
1174 DMC_VERSION_MINOR(dmc->version)); in intel_dmc_debugfs_status_show()
1203 intel_de_read(i915, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0))); in intel_dmc_debugfs_status_show()